Skip to content

Commit 1274d78

Browse files
authored
Merge pull request #7770 from QwikDev/documenthead-from-render
feat(ssr): pass additional `documentHead` via `serverData`
2 parents b98bd37 + bbfc9e4 commit 1274d78

File tree

26 files changed

+578
-103
lines changed

26 files changed

+578
-103
lines changed

.changeset/quiet-friends-taste.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/router': minor
3+
---
4+
5+
feat: `createRenderer()` wraps the `renderToStream()` function with Qwik Router types, for nicer `entry.ssr` files.

.changeset/stale-corners-flow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/router': minor
3+
---
4+
5+
feat: You can now put `documentHead` into the rendering functions as part of the `serverData` option. This is useful for passing title, meta tags, scripts, etc. to the `useDocumentHead()` hook from within the server.

e2e/adapters-e2e/src/entry.preview.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
*
1212
*/
1313
import { createQwikRouter } from '@qwik.dev/router/middleware/node';
14-
// make sure qwikCityPlan is imported before entry
1514
import render from './entry.ssr';
1615

1716
/** The default export is the QwikCity adapter used by Vite preview. */

e2e/adapters-e2e/src/entry.ssr.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,17 @@
99
* - Npm run preview
1010
* - Npm run build
1111
*/
12-
import { renderToStream, type RenderToStreamOptions } from '@qwik.dev/core/server';
12+
import { createRenderer } from '@qwik.dev/router';
1313
import Root from './root';
1414

15-
export default function (opts: RenderToStreamOptions) {
16-
return renderToStream(<Root />, {
15+
export default createRenderer((opts) => ({
16+
jsx: <Root />,
17+
options: {
1718
...opts,
1819
// Use container attributes to set attributes on the html tag.
1920
containerAttributes: {
2021
lang: 'en-us',
2122
...opts.containerAttributes,
2223
},
23-
// prefetchStrategy: {
24-
// implementation: {
25-
// linkInsert: "html-append",
26-
// linkRel: "modulepreload",
27-
// },
28-
// },
29-
serverData: {
30-
...opts.serverData,
31-
},
32-
});
33-
}
24+
},
25+
}));

packages/docs/src/entry.ssr.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { PreloaderOptions, RenderToStreamOptions } from '@qwik.dev/core/server';
2-
import { renderToStream } from '@qwik.dev/core/server';
1+
import { createRenderer } from '@qwik.dev/router';
32
import Root from './root';
43

54
// You can pass these as query parameters, as well as `preloadDebug`
@@ -10,9 +9,9 @@ const preloaderSettings = [
109
'preloadProbability',
1110
] as const;
1211

13-
export default function (opts: RenderToStreamOptions) {
12+
export default createRenderer((opts) => {
1413
const { serverData } = opts;
15-
const urlStr = serverData?.url;
14+
const urlStr = serverData.url;
1615
if (urlStr) {
1716
const { searchParams } = new URL(urlStr);
1817
if (searchParams.size) {
@@ -21,7 +20,7 @@ export default function (opts: RenderToStreamOptions) {
2120
preloader: {
2221
...(typeof opts.preloader === 'object' ? opts.preloader : undefined),
2322
},
24-
} as Omit<RenderToStreamOptions, 'preloader'> & { preloader: PreloaderOptions };
23+
};
2524
if (searchParams.has('preloaderDebug')) {
2625
newOpts.preloader!.debug = true;
2726
}
@@ -33,11 +32,14 @@ export default function (opts: RenderToStreamOptions) {
3332
opts = newOpts;
3433
}
3534
}
36-
return renderToStream(<Root />, {
37-
...opts,
38-
containerAttributes: {
39-
lang: 'en',
40-
...opts.containerAttributes,
35+
return {
36+
jsx: <Root />,
37+
options: {
38+
...opts,
39+
containerAttributes: {
40+
lang: 'en',
41+
...opts.containerAttributes,
42+
},
4143
},
42-
});
43-
}
44+
};
45+
});

packages/docs/src/routes/api/qwik-router/api.json

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@
8686
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
8787
"mdFile": "router.contentmenu.md"
8888
},
89+
{
90+
"name": "createRenderer",
91+
"id": "createrenderer",
92+
"hierarchy": [
93+
{
94+
"name": "createRenderer",
95+
"id": "createrenderer"
96+
}
97+
],
98+
"kind": "Function",
99+
"content": "Creates the `render()` function that is required by `createQwikRouter()`<!-- -->. It requires a function that returns the `jsx` and `options` for the renderer.\n\n\n```typescript\ncreateRenderer: (getOptions: (options: RendererOptions) => {\n jsx: JSXOutput;\n options: RendererOutputOptions;\n}) => Render\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\ngetOptions\n\n\n</td><td>\n\n(options: [RendererOptions](#rendereroptions)<!-- -->) =&gt; { jsx: JSXOutput; options: [RendererOutputOptions](#rendereroutputoptions)<!-- -->; }\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nRender\n\n\n\n```tsx\nconst renderer = createRenderer((opts) => {\n if (opts.requestHeaders['x-hello'] === 'world') {\n return { jsx: <Hello />, options: opts };\n }\n return { jsx: <Root />, options: {\n ...opts,\n serverData: {\n ...opts.serverData,\n documentHead: {\n meta: [\n { name: 'renderedAt', content: new Date().toISOString() },\n ],\n },\n },\n } };\n});\n```",
100+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/create-renderer.ts",
101+
"mdFile": "router.createrenderer.md"
102+
},
89103
{
90104
"name": "DataValidator",
91105
"id": "datavalidator",
@@ -506,6 +520,20 @@
506520
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
507521
"mdFile": "router.preventnavigatecallback.md"
508522
},
523+
{
524+
"name": "Q_ROUTE",
525+
"id": "q_route",
526+
"hierarchy": [
527+
{
528+
"name": "Q_ROUTE",
529+
"id": "q_route"
530+
}
531+
],
532+
"kind": "Variable",
533+
"content": "```typescript\nQ_ROUTE = \"q:route\"\n```",
534+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/constants.ts",
535+
"mdFile": "router.q_route.md"
536+
},
509537
{
510538
"name": "QWIK_CITY_SCROLLER",
511539
"id": "qwik_city_scroller",
@@ -618,6 +646,20 @@
618646
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
619647
"mdFile": "router.qwikrouterconfig.md"
620648
},
649+
{
650+
"name": "QwikRouterEnvData",
651+
"id": "qwikrouterenvdata",
652+
"hierarchy": [
653+
{
654+
"name": "QwikRouterEnvData",
655+
"id": "qwikrouterenvdata"
656+
}
657+
],
658+
"kind": "Interface",
659+
"content": "```typescript\nexport interface QwikRouterEnvData \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[ev](./router.qwikrouterenvdata.ev.md)\n\n\n</td><td>\n\n\n</td><td>\n\nRequestEvent\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[loadedRoute](./router.qwikrouterenvdata.loadedroute.md)\n\n\n</td><td>\n\n\n</td><td>\n\nLoadedRoute \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[params](./router.qwikrouterenvdata.params.md)\n\n\n</td><td>\n\n\n</td><td>\n\n[PathParams](#pathparams)\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[response](./router.qwikrouterenvdata.response.md)\n\n\n</td><td>\n\n\n</td><td>\n\nEndpointResponse\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[routeName](./router.qwikrouterenvdata.routename.md)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
660+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
661+
"mdFile": "router.qwikrouterenvdata.md"
662+
},
621663
{
622664
"name": "QwikRouterMockProps",
623665
"id": "qwikroutermockprops",
@@ -674,6 +716,34 @@
674716
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
675717
"mdFile": "router.qwikrouterprovider.md"
676718
},
719+
{
720+
"name": "RendererOptions",
721+
"id": "rendereroptions",
722+
"hierarchy": [
723+
{
724+
"name": "RendererOptions",
725+
"id": "rendereroptions"
726+
}
727+
],
728+
"kind": "TypeAlias",
729+
"content": "```typescript\nexport type RendererOptions = Omit<RenderOptions, 'serverData'> & {\n serverData: ServerData;\n};\n```\n**References:** [ServerData](#serverdata)",
730+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/create-renderer.ts",
731+
"mdFile": "router.rendereroptions.md"
732+
},
733+
{
734+
"name": "RendererOutputOptions",
735+
"id": "rendereroutputoptions",
736+
"hierarchy": [
737+
{
738+
"name": "RendererOutputOptions",
739+
"id": "rendereroutputoptions"
740+
}
741+
],
742+
"kind": "TypeAlias",
743+
"content": "```typescript\nexport type RendererOutputOptions = Omit<RenderOptions, 'serverData'> & {\n serverData: ServerData & {\n documentHead?: DocumentHeadValue;\n } & Record<string, unknown>;\n};\n```\n**References:** [ServerData](#serverdata)<!-- -->, [DocumentHeadValue](#documentheadvalue)",
744+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/create-renderer.ts",
745+
"mdFile": "router.rendereroutputoptions.md"
746+
},
677747
{
678748
"name": "ResolvedDocumentHead",
679749
"id": "resolveddocumenthead",
@@ -786,6 +856,20 @@
786856
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/server-functions.ts",
787857
"mdFile": "router.server_.md"
788858
},
859+
{
860+
"name": "ServerData",
861+
"id": "serverdata",
862+
"hierarchy": [
863+
{
864+
"name": "ServerData",
865+
"id": "serverdata"
866+
}
867+
],
868+
"kind": "TypeAlias",
869+
"content": "The server data that is provided by Qwik Router during SSR rendering. It can be retrieved with `useServerData(key)` in the server, but it is not available in the client.\n\n\n```typescript\nexport type ServerData = {\n url: string;\n requestHeaders: Record<string, string>;\n locale: string | undefined;\n nonce: string | undefined;\n containerAttributes: Record<string, string> & {\n [Q_ROUTE]: string;\n };\n qwikrouter: QwikRouterEnvData;\n};\n```\n**References:** [Q\\_ROUTE](#q_route)<!-- -->, [QwikRouterEnvData](#qwikrouterenvdata)",
870+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
871+
"mdFile": "router.serverdata.md"
872+
},
789873
{
790874
"name": "ServerFunction",
791875
"id": "serverfunction",

0 commit comments

Comments
 (0)