Skip to content

Commit f16f4d1

Browse files
committed
feat: support server-rendering attributes of <svelte:html> blocks
Companion to sveltejs/svelte#14397
1 parent fb146e7 commit f16f4d1

File tree

6 files changed

+26
-3
lines changed

6 files changed

+26
-3
lines changed

.changeset/tricky-garlics-mate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': minor
3+
---
4+
5+
feat: support server-rendering attributes of `<svelte:html>` blocks

documentation/docs/10-getting-started/30-project-structure.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ The `src` directory contains the meat of your project. Everything except `src/ro
4848
- `%sveltekit.assets%` — either [`paths.assets`](configuration#paths), if specified, or a relative path to [`paths.base`](configuration#paths)
4949
- `%sveltekit.nonce%` — a [CSP](configuration#csp) nonce for manually included links and scripts, if used
5050
- `%sveltekit.env.[NAME]%` - this will be replaced at render time with the `[NAME]` environment variable, which must begin with the [`publicPrefix`](configuration#env) (usually `PUBLIC_`). It will fallback to `''` if not matched.
51+
- `%svelte.htmlAttributes%` — the attributes collected from `<svelte:html>` blocks
5152
- `error.html` is the page that is rendered when everything else fails. It can contain the following placeholders:
5253
- `%sveltekit.status%` — the HTTP status
5354
- `%sveltekit.error.message%` — the error message

packages/kit/src/core/sync/write_server.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_
3737
export const options = {
3838
app_dir: ${s(config.kit.appDir)},
3939
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
40+
app_template_contains_svelte_htmlAttributes: ${template.includes('%svelte.htmlAttributes%')},
4041
csp: ${s(config.kit.csp)},
4142
csrf_check_origin: ${s(config.kit.csrf.checkOrigin)},
4243
embedded: ${config.kit.embedded},
@@ -47,7 +48,8 @@ export const options = {
4748
root,
4849
service_worker: ${has_service_worker},
4950
templates: {
50-
app: ({ head, body, assets, nonce, env }) => ${s(template)
51+
app: ({ html_attributes, head, body, assets, nonce, env }) => ${s(template)
52+
.replace('%svelte.htmlAttributes%', '" + html_attributes + "')
5153
.replace('%sveltekit.head%', '" + head + "')
5254
.replace('%sveltekit.body%', '" + body + "')
5355
.replace(/%sveltekit\.assets%/g, '" + assets + "')

packages/kit/src/runtime/server/page/render.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,17 @@ export async function render_response({
191191
}
192192
}
193193
} else {
194-
rendered = { head: '', html: '', css: { code: '', map: null } };
194+
rendered = { head: '', html: '', css: { code: '', map: null }, htmlAttributes: '' };
195+
}
196+
197+
if (
198+
!options.app_template_contains_svelte_htmlAttributes &&
199+
// @ts-expect-error only exists in later versions of Svelte 5
200+
rendered.htmlAttributes
201+
) {
202+
console.warn(
203+
'One or more components used `<svelte:html>` to output attributes to the HTML tag but app.html does not contain %svelte.htmlAttributes% to render them. The attributes will be ignored.'
204+
);
195205
}
196206

197207
let head = '';
@@ -458,6 +468,9 @@ export async function render_response({
458468
head += rendered.head;
459469

460470
const html = options.templates.app({
471+
// @ts-expect-error only exists in later versions of Svelte 5
472+
html_attributes: rendered.htmlAttributes ?? '',
473+
461474
head,
462475
body,
463476
assets,

packages/kit/src/types/internal.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ export type SSRNodeLoader = () => Promise<SSRNode>;
355355
export interface SSROptions {
356356
app_dir: string;
357357
app_template_contains_nonce: boolean;
358+
app_template_contains_svelte_htmlAttributes: boolean;
358359
csp: ValidatedConfig['kit']['csp'];
359360
csrf_check_origin: boolean;
360361
embedded: boolean;
@@ -366,6 +367,7 @@ export interface SSROptions {
366367
service_worker: boolean;
367368
templates: {
368369
app(values: {
370+
htmlAttributes: string;
369371
head: string;
370372
body: string;
371373
assets: string;

playgrounds/basic/src/app.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!doctype html>
2-
<html lang="en">
2+
<html %svelte.htmlAttributes% lang="en">
33
<head>
44
<meta charset="utf-8" />
55
<link rel="icon" href="%sveltekit.assets%/favicon.png" />

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy