Load YAML in Svelte
2 min read

Load YAML in Svelte

Load YAML in Svelte

I'm writing a dashboard app in svelte, so I have shortcuts for all my home infrastructure.

Options

Although I can do it in static mode (all values and things are hardcoded), I wanted to create a config file and generate the page based on it.

From a format perspective, I can do a JSON. It can be natively loaded, but it's harder to understand and quite restrictive (e.g. no comments). YAML is a bit easier to understand (although the formatting is somewhat more difficult). I can also add comments, so other users can understand what I really want there.

I've seen other dashboards made in Angular, React or plain shell script. I picked up Svelte because... well, because I like it.

Loading YAML

One can write a server-side thing to load the YAML file, but I wanted to do it client-side (SSR to be more exact). Svelte allows me to compile my code and actually execute some of it as part of the compilation process.

The trick is to use a load() function, which is executed when the module is parsed (at least that's my understanding).

I've split the code in two files:

  1. a js file dealing with the YAML loading and
  2. a section in a svelte component (__layout.svelte in my case) which allows me to execute the YAML loader.

The YAML loader

The code exposes a function which loads a config file from a specific (relative) location and is quite simple:

//
// /src/routes/index.json.js
//

import fs from 'fs';
import yaml from 'js-yaml';

export function get() {
  let config = yaml.load(fs.readFileSync('src/config.yml').toString());
  let body = JSON.stringify(config);

  return { body };
}

As you can see, you need fs to access the filesystem and js-yaml to load the yaml file.

Loader Execution

In __layout.svelte I have a script with the context="module" scope:

<script context="module" lang="ts">
  import { base } from '$app/paths';

  /**
   * @type {import('@sveltejs/kit').Load}
   */
  export async function load({ fetch }) {
    const config = await fetch(`${base}/index.json`).then((r) => r.json());

    return {
      props: { config },
    };
  }
</script>

This basically loads index.json.js, executes it and stores the JSON result in a property named config

Another small script (this time with a local context) will define this property so the above script can populate it:

<script lang="ts">
  export let config: any;
</script>

At this point, you can use the configuration data in the __layout.svelte file. I use some of it to populate some of the navigation section of the site.

HTH,