This repo illustrates, how to host a multi page svelte application on github pages. The crux of implementation is to do rendering on client side rather than server side.
To understand, how it works, let me first explain few terminologies with the help of chatGPT.
Server side rendering (ssr
)
In SSR, the server generates the full HTML for a web page and sends it to the client. This means that when a user requests a page, the server processes the request, fetches the necessary data, and dynamically generates the HTML on the server side. The fully rendered HTML is then sent to the client's browser, where it's displayed to the user. This approach is often associated with traditional web applications.
This is how github pages work, it serves fully rendered html pages, which with dynamic routing is difficult to do. As in dynamic routing, you could have a template for blog posts, and based on the data (like different blog post titles), the application can dynamically generate URLs for each blog post. So, instead of creating individual HTML files for each post, you have a single template that's populated with content based on the requested URL.
Client side rendering (csr
)
In CSR, the server sends a minimal HTML document to the client, along with JavaScript. The client's browser then executes the JavaScript to dynamically generate and render the content. This approach is common in single-page applications (SPAs) where most of the rendering and navigation happens on the client side.
onMount
function. This runs as soon as the component has been mounted to the DOM. We will add this function to our +page.svelte
, so as soon as the page is hit, the function renders the page. For example:
<script>
import { onMount } from 'svelte';
import { page } from '$app/stores';
let data = {};
onMount(() => {
console.log('page is mounted');
console.log(`url is ${$page.url}`);
let paramstr = JSON.stringify($page.params);
console.log(`params are ${paramstr}`);
data = {
title: $page.params.slug,
content: $page.params.slug
};
});
</script>
ssr=false
and prerender=false
in +page.js
static-adapter
as shown here and update the svelte.config.js
as follows:
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
pages: 'build',
assets: 'build',
strict: false,
fallback: '404.html'
}),
appDir: 'appDir',
paths: {
assets: 'https://mohit2152sharma.github.io/svelte-mpa-example',
base: '/svelte-mpa-example',
}
}
};
export default config;
fallback
: This is the page, the app will redirect to incase of error. The error is bound to happen, as github will look for a dynamic page to serve and since it doesn't exist, it will redirect to fallback
. In github's case, the error page lives 404.html
. Read more here.paths.assets
is https://{github-username}.github.io/{repo-name}
. If not set, the app would throw a TypeError: Failed to fetch dynamically imported module: https://mohit2152sharma.github.io/_app/immutable/entry/start.a84ced15.js
error. As you can see in the error, it is not using the right path to look for .js
file, setting paths.assets
enforces that.paths.base
is your github repo name. The name must not end with a forward slash.github-action
to deploy your site, to github pages, for reference you can use this repo's github-action. You may also need to change few settings, if you are using github action.This is a light weight application, to see how it is working, you can navigate to the homepage and from there, to the following links:
/blog/[blog-name]
: Any value you pass as a blog name will be shown on the web page. For example: hello-world /qna?id={id}
: This endpoint demonstrates, how to handle query parameters. For example: id=1