21

Is it possible to build a SvelteKit project to a single output HTML file which inlines all JS and CSS? Could SvelteKit be configured to support this output format or do I need to use an external build tool?

The single HTML file output is a core requirement in my project. I'm building a SvelteKit SPA using ssr: false and @sveltejs/adapter-static with the fallback: 'index.html' config.

I've previously used https://github.com/richardtallent/vite-plugin-singlefile to accomplish this with a simple vite + svelte setup - this worked great. However, I'm unable to add vite-plugin-singlefile to the svelte.config.js vite plugins in my SvelteKit project.

This is the SvelteKit config I've tried:

import preprocess from 'svelte-preprocess'
import adapter from '@sveltejs/adapter-static'
import { viteSingleFile } from 'vite-plugin-singlefile'

const config = {
    preprocess: preprocess(),
    kit: {
        target: '#svelte',
        adapter: adapter({ fallback: 'index.html' }),
        ssr: false,
        vite: {
            plugins: [viteSingleFile()],
            build: {
                target: 'es2019',
                assetsInlineLimit: 100000000,
                chunkSizeWarningLimit: 100000000,
                cssCodeSplit: false,
                sourcemap: false,
                brotliSize: false,
                rollupOptions: {
                    inlineDynamicImports: true,
                    output: {
                        manualChunks: () => 'everything.js',
                    },
                },
                outDir: 'build'
            }
        }
    },
}

export default config

I've also looked into using other solutions to inline all CSS and JS:

Any ideas would be helpful!

Samuel Plumppu
  • 325
  • 2
  • 13
  • 2
    Not sure if it's currently possible to inline everything, but there is an issue in the repo for inlining CSS at least: https://github.com/sveltejs/kit/issues/962 – Nick Jun 09 '21 at 19:01
  • 2
    Thanks @Nick! I've done some further research and seems like SvelteKit itself is not ready for building SPA:s with fully inlined assets at the moment, but it will be interesting to follow future development. In the meantime, I will continue using `vite` + `svelte` + `vite-plugin-singlefile` as it covers my needs. Let's keep this question open for future potential solutions though! – Samuel Plumppu Jun 10 '21 at 08:38
  • 2
    I've recently raised an issue for going the other way (externalise everything), as inline scripts seem to be problematic for chrome extensions in manifest v3: https://github.com/sveltejs/kit/issues/1776 Externalising the ` – Joe Jun 29 '21 at 14:43
  • 1
    I create SPA apps with Svelte and publish to Sharepoint sitepages. Since i can't access Sharepoint API via localhost when developing with Svelte dev server, i have to upload the site frequently to test and debug API calls. But, because Sharepoint caches js and css files, new versions of the sitei upload continue to use previous cached js and css files. So single HTML with everything-inlined is the only solution for me right now. Been using `vite` + `svelte` + `vite-plugin-singlefile` which works great. But i would like to switch to SvelteKit too and very interested in a solution. – Sateesh Jan 06 '23 at 08:39
  • The same need exists if you're building a Figma plugin. @SamuelPlumppu did you get anywhere with this? – limitlessloop Mar 06 '23 at 09:49
  • 1
    @limitlessloop I've not tried this recently, but it might be possible to use `@sveltejs/adapter-static` and build a SvelteKit SPA https://kit.svelte.dev/docs/single-page-apps. Then, maybe it's possible to use https://github.com/richardtallent/vite-plugin-singlefile to compile into a single HTML file. – Samuel Plumppu Mar 06 '23 at 15:54

1 Answers1

2

This is a low-tech solution, but you can replace links to CSS and JS files with style and script tags, respectively. Then copy-paste the contents of those files between the tags.

As long as you put the style/script tags in the same place as you had previously linked your CSS and JS, there shouldn't be any major problems (though any JS scripts with defer will need to go in an event handler saying to only run the contents of that script the page is fully loaded).

Of course, you're using imported files, so this is all contingent on you being able to access their source code. If you can't access it, then needless to say you won't be able to copy-paste it into your HTML file.