Published on

Creating This Project

Categorised under

Initially, I wanted to make a rewrite of a personal webpage using sapper, markdown, tailwindcss and typescript. However, since sveltekit would replace sapper, I went with that instead.

Installation process

npm init svelte@next test
cd test
npx svelte-add tailwindcss # automatically installs postcss
npx svelte-add mdsvex
npm install
npm i -D npm-run-all postcss-import autoprefixer cssnano
npm run serve

npm i rehype-katex-svelte // Test if this can render math expressions.
npm install -D remark-math@3.0.0
shell

Several fixes were made to improve the setup of the project.

  • include common folder paths under svelte.config.js
    vite.resolve.alias
    and tsconfig.json
    compilerOptions.paths
    for convenience
  • replace app.css

Setup for static site

If planning to use the static adapter, note that it doesn’t support things like [slug].json.ts which have to be rendered by the server based on the route. (Button links all work fine but direct url visit would fail.)

// svelte.config.js
import adapter from '@sveltejs/adapter-static';
const config = {
    kit: {
        adapter: adapter({
                         // default options are shown
        pages: 'build',
        assets: 'build',
        fallback: null
        })
    }
};
js
// package.json
{
    "scripts": {
        // github
        "build": "rm -rf build && svelte-kit build && touch build/.nojekyll",
            "deploy": "npm run build && npx gh-pages -d build -t true",

            // surge
            "build": "svelte-kit build",
            "deploy": "npm run build && surge --project ./build/ --domain https://ngxingyu.surge.sh"
    }
}
json

Setup with vercel

  • First, insert
    "@sveltejs/adapter-vercel": "next",
    in package.json and run
    npm upgrade; npm install
    in the terminal.
  • Then, insert the following into svelte.config.js and run
    npm run build
    to test the deployment.
import vercel from '@sveltejs/adapter-vercel';
const config = { kit: { adapter: vercel() } };
js
  • Lastly, add the generated

    .vercel_build_output
    folder to .gitignore, and push the changes to github.

  • For the vercel setup, simple proceed to Vercel, create your account, import the repo to your account, and set the default settings for ‘Svelte’

Sitemap generation

  • Install the following packages:

    npm install -D fast-glob xmlbuilder2"

  • Add the deployment url to package.json

  • Run the following as part of the postbuild process.

node --experimental-json-modules ./generate-sitemap.js

Components created

Mdsvex Code wrapper

The mdsvex package allows for the generation of pages using markdown with support for svelte components and a frontmatter containing general information of pages. Currently, the markdown code blocks can be created using

` `
and

``` ```

These generates a basic html code block and a div which supports more advanced language highlighting using prism.js. In order to display the language used and support a copy to clipboard operation, I created a

<C>
component wrapper for the multiline code blocks, and a custom code component to replace any instance of the
<code>
element. To use:

Multiline codeblock

<C lang="md">
**insert line before any md content you want mdsvex to parse** w
```md
- insert sample code here
```

</C>
md

Inline codeblock

`<p>A code wrapper for inline code block with a click to copy function</p>`

How it is made

Simply create the custom code component, and override the default component within the layout file to replace all instances of code with the custom code component.

<!--inlineCheckbox.svelte-->
<script lang="ts">
	import { tick } from 'svelte';
	let code: HTMLElement;
	async function copy() {
await tick();
code.focus();
const output = code.textContent;
navigator.permissions.query({ name: 'clipboard-write' }).then((result) => {
	if (result.state == 'granted' || result.state == 'prompt') {
		navigator.clipboard.writeText(output);
	}
});
	}
</script>
<div bind:this={code} on:click={copy} class="inline hover:ring-2 active:bg-green-300"><code><slot /></code></div>
svelte
// components/components.js
export { default as code } from './InlineCode.svelte';
js
<!--layout.svelte-->
<script context="module">
    import { code } from "$components/components.js";
    export { code };
</script>
svelte

Plop.js

npm install --save-dev plop
npm install -g plop

To use, simply run

npm run generate

and follow the instructions.

Search functionality for page content

My search is done by indexing each markdown file in the prebuild, recording the inverse document frequency of token for each document within a json file. The bm25 score of each document is calculated on runtime using the formula 1+11+1

IDF(TF(k1+1))/(TF+k1(1b+b documentLength / averageDocumentLength ))IDF * (TF * (k1 + 1)) / (TF + k1 * (1 - b + b * \text{ documentLength } / \text{ averageDocumentLength }))