Skip to content

Commit 041ce21

Browse files
rsbhclaude
andcommitted
feat: inject CSS and JS assets into SSR HTML head
Use Nitro ?assets=client/ssr virtual imports to collect CSS/JS assets and inject as <link> tags in HTML <head>. Fixes unstyled flash on initial page load. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 50ecc6d commit 041ce21

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

  • packages/chronicle/src/server/routes

packages/chronicle/src/server/routes/[...].ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { loadConfig } from '@/lib/config';
66
import { loadApiSpecs } from '@/lib/openapi';
77
import { buildPageTree, getPage, loadPageComponent } from '@/lib/source';
88
import { render } from '../entry-server';
9+
// @ts-expect-error virtual import from Nitro
10+
import clientAssets from '../entry-client?assets=client';
11+
// @ts-expect-error virtual import from Nitro
12+
import serverAssets from '../entry-server?assets=ssr';
913

1014
export default defineHandler(async event => {
1115
const pathname = event.url.pathname;
@@ -46,6 +50,14 @@ export default defineHandler(async event => {
4650

4751
const appHtml = await render(event.url.href, { config, tree, page: pageData, apiSpecs });
4852

53+
const assets = clientAssets.merge(serverAssets);
54+
const cssLinks = assets.css.map((attr: { href: string }) =>
55+
`<link rel="stylesheet" href="${attr.href}" />`
56+
).join('\n ');
57+
const jsPreloads = assets.js.map((attr: { href: string }) =>
58+
`<link rel="modulepreload" href="${attr.href}" />`
59+
).join('\n ');
60+
4961
const safeJson = JSON.stringify(embeddedData).replace(/</g, '\\u003c');
5062
const dataScript = `<script>window.__PAGE_DATA__ = ${safeJson}</script>`;
5163

@@ -54,11 +66,13 @@ export default defineHandler(async event => {
5466
<head>
5567
<meta charset="UTF-8" />
5668
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
69+
${cssLinks}
70+
${jsPreloads}
5771
${dataScript}
5872
</head>
5973
<body>
6074
<div id="root">${appHtml}</div>
61-
<script type="module" src="/src/server/entry-client.tsx"></script>
75+
<script type="module" src="${assets.entry}"></script>
6276
</body>
6377
</html>`;
6478

0 commit comments

Comments
 (0)