Skip to content

Commit de55416

Browse files
authored
change: mark generateSetInitialModeExpression as deprecated in favor of createInitialModeExpression (#132)
1 parent 3102c86 commit de55416

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

.changeset/four-humans-fail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mode-watcher": patch
3+
---
4+
5+
change: mark `generateSetInitialModeExpression` as deprecated in favor of `createInitialModeExpression`
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: createInitialModeExpression
3+
description: Creates a secure inline script to set the initial mode (light, dark, or system) before hydration.
4+
section: Utilities
5+
---
6+
7+
<script>
8+
import { Callout } from '@svecodocs/kit'
9+
</script>
10+
11+
`createInitialModeExpression` outputs a small, inline JavaScript snippet as a string.
12+
13+
It's typically used alongside server-rendered HTML and injected into the page head securely using SvelteKit's `transformPageChunk`.
14+
15+
## When to Use
16+
17+
Use `createInitialModeExpression` when:
18+
19+
- You're operating under a Content Security Policy (CSP) that requires a `nonce` for inline scripts.
20+
- You're rendering the initial page via SvelteKit server hooks and want to inject logic at render time.
21+
22+
This approach is ideal for security-sensitive environments or platforms with strict CSP headers, where inline scripts must include a trusted nonce.
23+
24+
## Usage
25+
26+
To use `createInitialModeExpression`, you need two things:
27+
28+
### 1. Modify `app.html`
29+
30+
Add the following placeholder in the `<head>` of your `app.html` file:
31+
32+
```html title="app.html"
33+
<script nonce="%sveltekit.nonce%">
34+
%modewatcher.snippet%
35+
</script>
36+
```
37+
38+
This placeholder will be replaced server-side at render time.
39+
40+
### 2. Update `hooks.server.ts`
41+
42+
Inject the snippet during SSR using `transformPageChunk`:
43+
44+
```ts title="hooks.server.ts"
45+
import { createInitialModeExpression } from "mode-watcher";
46+
47+
export const handle: Handle = async ({ event, resolve }) => {
48+
return resolve(event, {
49+
transformPageChunk: ({ html }) =>
50+
html.replace("%modewatcher.snippet%", createInitialModeExpression()),
51+
});
52+
};
53+
```
54+
55+
<Callout type="tip">
56+
57+
If you're planning to inject multiple types of initial client-side logic (e.g., directionality, locale), consider using a shared `%placeholder%` strategy with `transformPageChunk`.
58+
59+
</Callout>
60+
61+
## Credits
62+
63+
Thanks to [@fnimick](https://github.com/fnimick) for contributing and validating this approach.

packages/mode-watcher/src/lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
generateSetInitialModeExpression,
3+
createInitialModeExpression,
34
resetMode,
45
setMode,
56
setTheme,
@@ -11,6 +12,7 @@ import { userPrefersMode, systemPrefersMode } from "./mode-states.svelte.js";
1112

1213
export {
1314
generateSetInitialModeExpression,
15+
createInitialModeExpression,
1416
setMode,
1517
toggleMode,
1618
resetMode,

packages/mode-watcher/src/lib/mode.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,14 @@ export function setInitialMode({
8282

8383
/**
8484
* A type-safe way to generate the source expression used to set the initial mode and avoid FOUC.
85+
*
86+
* @deprecated Use `createInitialModeExpression` instead.
8587
*/
8688
export function generateSetInitialModeExpression(config: SetInitialModeArgs = {}): string {
8789
return `(${setInitialMode.toString()})(${JSON.stringify(config)});`;
8890
}
91+
92+
/**
93+
* A type-safe way to generate the source expression used to set the initial mode and avoid FOUC.
94+
*/
95+
export const createInitialModeExpression = generateSetInitialModeExpression;

0 commit comments

Comments
 (0)