new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Svelte · SvelteKit · all subjects

best-practices

29 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Better Auth setup with SvelteKit

The Svelte CLI provides an option to set up Better Auth with a new project or add it to an existing project.

Lucia auth guide for SvelteKit

The Lucia auth guide at lucia-auth.com provides a reference for implementing session-based web app authentication with SvelteKit examples.

Sessions vs tokens for authentication

After user credentials are verified, subsequent requests can use either a session identifier or a signed token like JWT. Session IDs are stored in a database and can be immediately revoked but require a database query on each request. JWT tokens are generally not checked against a datastore, so they cannot be immediately revoked, but provide improved latency and reduced datastore load.

CSS-based icons with Iconify

Icons can be defined purely via CSS using Iconify, which offers support for many popular icon sets. Iconify icons can be included via CSS and work with popular CSS frameworks by leveraging the Iconify Tailwind CSS plugin or UnoCSS plugin. This method does not require icons to be imported into .svelte files.

Avoid Svelte icon libraries with one file per icon

When choosing icon libraries for Svelte, avoid libraries that provide a .svelte file per icon. These libraries can have thousands of .svelte files which significantly slow down Vite's dependency optimization. This performance degradation becomes especially severe if icons are imported both via umbrella imports and subpath imports.

Route announcements and live regions in client-side routing

SvelteKit uses client-side routing where navigation between pages happens without reloading the page. To inform screen readers and assistive technology about page changes, SvelteKit injects a live region that reads out the new page name after each navigation. The page name is determined by inspecting the <title> element. Every page in your app should have a unique, descriptive title using a <svelte:head> element to allow assistive technology to identify the new page after navigation.

Focus management during client-side routing

During client-side routing, SvelteKit focuses the <body> element after each navigation and enhanced form submission to simulate the behavior of traditional server-rendered applications where focus resets to the top of the page. However, if an element with the autofocus attribute is present, SvelteKit will focus that element instead. The afterNavigate hook can be used to customize focus management behavior.

goto function with keepFocus option

The goto function from $app/navigation can programmatically navigate to a different page with the same client-side routing behavior as clicking a link. It accepts a keepFocus option that preserves the currently-focused element instead of resetting focus. If keepFocus is enabled, ensure the currently-focused element still exists on the page after navigation to prevent the user's focus from being lost.

Setting the lang attribute in SvelteKit

SvelteKit's page template sets the default language of the document to English. If content is not in English, update the <html> element in src/app.html to have the correct lang attribute. For multi-language content, set the lang attribute based on the language of the current page using SvelteKit's handle hook with the transformPageChunk option to replace a placeholder like %lang% in the HTML.

SSR enabled by default for SEO

SvelteKit employs server-side rendering (SSR) by default, which search engines index more frequently and reliably than client-side rendered content. You can disable SSR in the handle hook if necessary, but you should leave it on unless you have a good reason not to.

Core Web Vitals impact search engine ranking

Signals such as Core Web Vitals impact search engine ranking. Svelte and SvelteKit introduce minimal overhead, making it easier to build high performance sites. Using SvelteKit's default hybrid rendering mode and optimizing images can greatly improve site speed.

SvelteKit normalizes trailing slash URLs

SvelteKit redirects pathnames with trailing slashes to ones without (or vice versa depending on configuration), as duplicate URLs are bad for SEO.

Title and meta description on every page

Every page should have well-written and unique <title> and <meta name="description"> elements inside a <svelte:head>. A common pattern is to return SEO-related data from page load functions, then use it as page.data in a <svelte:head> in your root layout.

Creating dynamic sitemaps with endpoints

Sitemaps help search engines prioritize pages within your site, particularly with large amounts of content. You can create a sitemap dynamically using a server endpoint at src/routes/sitemap.xml/+server.js that returns XML with proper Content-Type header 'application/xml'.

AMP implementation with inlineStyleThreshold

To create an Accelerated Mobile Pages (AMP) version of a SvelteKit site, set the inlineStyleThreshold configuration option to Infinity to inline all styles, since <link rel="stylesheet"> is not allowed in AMP.

Disable CSR for AMP pages

To support AMP pages in SvelteKit, set export const csr = false in your root +layout.server.js or +layout.js file.

AMP html element and transformPageChunk

To implement AMP support, add the amp attribute to the html element in app.html and use transformPageChunk in src/hooks.server.js with the transform function imported from @sveltejs/amp to transform the HTML.

Remove unused CSS for AMP with dropcss

When transforming pages to AMP, use the dropcss package to prevent shipping unused CSS. The tool processes the markup and CSS to remove styles not used in the AMP document.

Validate AMP HTML with amphtml-validator

Use the handle hook to validate transformed HTML using amphtml-validator, but only if you're prerendering pages since validation is very slow.

Dynamic rendering is possible but not generally recommended

SvelteKit's rendering is highly configurable and you can implement dynamic rendering if necessary, but it's not generally recommended since SSR has other benefits beyond SEO.

error() and redirect() no longer require throw in v2

In SvelteKit 2, you no longer need to throw the values returned from error(...) and redirect(...) functions. Calling the functions directly is sufficient. Previously in version 1, you had to throw these values manually.

path parameter required for cookie operations in v2

As of SvelteKit 2.0, a path parameter must be provided when calling cookies.set(), cookies.delete(), or cookies.serialize(). Common values are path: '/' for domain-wide cookies, '' for the current path, or '.' for the current directory. This prevents ambiguous browser cookie path behavior.

Server fetch tracking removed in v2

The dangerZone.trackServerFetches setting has been removed in SvelteKit 2. Previously it allowed tracking URLs from server fetches to rerun load functions, but this posed a security risk of private URL leakage.

isHttpError and isRedirect helpers for error handling in v2

In SvelteKit 2, if error or redirect is thrown inside a try block, you can distinguish them from unexpected errors using isHttpError and isRedirect functions imported from @sveltejs/kit.

$lib/server prevents client-side imports

$lib/server is a subdirectory of $lib. SvelteKit will prevent you from importing any modules in $lib/server into client-side code, enforcing server-only module usage.

Library packaging requirements

When checking if a library is packaged correctly: (1) exports field takes precedence over other entry point fields like main and module; adding an exports field may not be backwards-compatible as it prevents deep imports. (2) ESM files should end with .mjs unless type: module is set in package.json, in which case CommonJS files should end with .cjs. (3) main should be defined if exports is not, and should be either a CommonJS or ESM file adhering to the previous bullet; if a module field is defined, it should refer to an ESM file. (4) Svelte components should be distributed as uncompiled .svelte files with any JS in the package written as ESM only; custom script and style languages like TypeScript and SCSS should be preprocessed as vanilla JS and CSS respectively.

Database query best practices

Put the code to query your database in a server route, not in .svelte files. Create a db.js or similar that sets up a connection immediately and makes the client accessible throughout the app as a singleton. Execute any one-time setup code in hooks.server.js and import your database helpers into any endpoint that needs them.

Using client-side libraries with document or window

If you need access to document or window variables or need code to run only on the client-side, wrap it in a browser check using import { browser } from '$app/environment'; and then if (browser) { /* client-only code here */ }. Alternatively, you can run code in onMount to run it after the component has been first rendered to the DOM. You can also use await blocks to conditionally import different components for browser versus server environments.

Using external API servers

You can use event.fetch to request data from an external API server, but be aware that you need to deal with CORS, which generally requires requests to be preflighted resulting in higher latency. Another approach is to set up a proxy to bypass CORS headaches. In production, rewrite a path like /api to the API server; for local development, use Vite's server.proxy option. How to set up rewrites in production depends on your deployment platform. If rewrites aren't an option, you can add an API route in src/routes/api/[...path]/+server.js. You may also need to proxy POST/PATCH requests and forward request.headers depending on your needs.

Give your agent this brain