1

I am building my routes like this:

import Component from "./Component.svelte";
import LangComponent from "./LangComponent.svelte";

const buildRoutes = [
  { name: "/", component: Component },
  {
    name: "hello-world",
    component: LangComponent,
    lang: { de: "hallo-welt" },
  },
];

export default buildRoutes.map(route => ({
  ...route,
  layout: PublicLayout,
}));

I want to generate a static sitemap.xml in my public folder for all the (good) bots in the world to crawl. It should have this format:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://www.mycoolsite.com</loc>
        <xhtml:link 
               rel="alternate"
               hreflang="de"
               href="http://www.example.com/deutsch/page.html"/>
    <lastmod>2020-06-04</lastmod>
  </url>
</urlset>

So basically I have to add a <loc> when there is an element with only a name property and additionally a <xhtml:link element when the route is also localized.

What is the best way to do this? I have tried so far:

  • Writing a bash script which greps the routes and generates a new file --> Too complicated with this structure (also way above my grep expertise).
  • Using a custom npm commmand to import the array in a javascript file and use the fs module --> Ran into problems with babel which seems to not like the imported svelte files.
    • Do the same as above, but in an imported javascript file in my App.svelte to not run into the babel problem. The problem is now that as it does not run in the browser, there is no fs I can use.

Is there a way to do this? Can this maybe be done in rollup? There seem to be some solutions in sapper, but I don't use it.

Gh05d
  • 7,923
  • 7
  • 33
  • 64
  • 1
    I would store the route definition in a separate JSON or YAML file, and import it wherever needed, i.e. in your Svelte project for actual routing, or in a node script to generate the sitemap file(s). The sitemap generation doesn't belong online anyway, it's a script that should be run periodically (as a cron task, for example), with the resulting sitemap(s) published into the public/static directory of your distribution. – Thomas Hennes Jun 04 '20 at 16:38
  • The problem with this approach is that I run into the Babel Problem again, because I have to import the Components which belong to the routes. – Gh05d Jun 05 '20 at 08:32
  • 1
    That can easily be solved by storing the component references as string constants in your route definition file (e.g.: component: "LangComponent") and having a table lookup in your Svelte file (`componentLookup = { "LangComponent": LangComponent, ... }`), then use `component: componentLookup[route.component]` in your mapping. A bit tedious but it works. Maybe there is a way to directly de-reference a string constant into the equivalent component? – Thomas Hennes Jun 05 '20 at 10:41
  • Sounds promising and tedious. But it seems like in this case there are no *good* solutions. – Gh05d Jun 05 '20 at 13:21

0 Answers0