Essential Insights for Launching a SvelteKit Application
Written on
Chapter 1: Preparing for Production
Before you take your SvelteKit application live, there are several important factors to consider. These elements include content security policy, ensuring build reproducibility, and the use of polyfills. Here, I’ll share some insights gained from a recent experience that may help you deploy your apps more securely.
Last week, the latest version of NNS-dapp (the decentralized application of NNS, one of the largest DAOs managing the Internet Computer) rolled out a new feature called "Stake Maturity," along with a subtle redesign of its modals and an update to its build system. The frontend, previously reliant solely on the Rollup bundler, has transitioned to SvelteKit*, which integrates Vite, esbuild, and Rollup.
- Content Security Policy Issues in Firefox
One critical lesson learned is regarding the Content Security Policy (CSP). This security feature is essential for detecting and preventing attacks, such as Cross-Site Scripting (XSS) and data injection (source: MDN). Given our commitment to security, we adopted strict CSP rules, particularly around the script-src directive to whitelist script tags in our index.html using their SHA256 hashes, and the script-dynamic policy for loading necessary code chunks.
While this configuration worked well with the previous bundler, we encountered unexpected issues with SvelteKit (as of October 2022). The combination of policies worked in Chrome and Safari but caused complete app failure in Firefox. To resolve this, we devised a workaround: implementing a post-build script to extract the injected code into a separate JS file and replace it with our own script loader.
To implement this workaround, follow these steps:
- Create an empty main.js in the static folder (this aids in local development).
- Insert a script loader in the <head> section of your root HTML page (i.e., in src/app.html).
- Develop a post-build script, for instance, ./scripts/build.csp.mjs.
Here’s a basic template for the script:
#!/usr/bin/env node
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
const publicIndexHTML = join(process.cwd(), "public", "index.html");
const buildCsp = () => {
const indexHTMLWithoutStartScript = extractStartScript();
writeFileSync(publicIndexHTML, indexHTMLWithoutStartScript);
};
// The extraction function to manage CSP issues
const extractStartScript = () => {
const indexHtml = readFileSync(publicIndexHTML, "utf-8");
const svelteKitStartScript = /<script>.*</script>/; // Adjust regex to match the injected script
// Additional logic to modify indexHtml as needed
};
Note: This transition was made without altering routing.
Section 1.1: Additional Tips for SvelteKit Deployment
When deploying your SvelteKit application, consider the following best practices to ensure a smooth launch.
Subsection 1.1.1: Utilizing Modern Web Technologies
To enhance your application's capabilities, it’s vital to harness the latest web technologies. This allows for a more seamless user experience and improved performance.