Skip to content

Commit 29a9b6f

Browse files
Enable SSR for 11ty (#1400)
1 parent f7f52c4 commit 29a9b6f

File tree

12 files changed

+76
-48
lines changed

12 files changed

+76
-48
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"./packages/custom-elements-manifest-tools:build",
5555
"./packages/catalog-api:build",
5656
"./packages/catalog-server:build",
57+
"./packages/site-server:build",
5758
"./packages/site-content:build",
5859
"./packages/site-client:build"
5960
]

packages/site-client/src/components/wco-catalog-page.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import {html, css, LitElement} from 'lit';
88
import {customElement} from 'lit/decorators.js';
9-
import './wco-top-bar.js';
109
import './wco-catalog-search.js';
1110

1211
@customElement('wco-catalog-page')
@@ -19,7 +18,6 @@ export class WCOCatalogPage extends LitElement {
1918

2019
render() {
2120
return html`
22-
<wco-top-bar></wco-top-bar>
2321
<h1>Catalog</h1>
2422
<wco-catalog-search></wco-catalog-search>
2523
`;

packages/site-client/src/components/wco-element-page.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {
1515
normalizeModulePath,
1616
} from '@webcomponents/custom-elements-manifest-tools';
1717

18-
import './wco-top-bar.js';
19-
2018
export interface ElementData {
2119
packageName: string;
2220
elementName: string;
@@ -46,10 +44,7 @@ export class WCOElementPage extends LitElement {
4644

4745
render() {
4846
if (this.elementData === undefined) {
49-
return html`
50-
<wco-top-bar></wco-top-bar>
51-
<div class="full-screen-error">No element to display</div>
52-
`;
47+
return html` <div class="full-screen-error">No element to display</div> `;
5348
}
5449
const {
5550
packageName,
@@ -71,7 +66,6 @@ export class WCOElementPage extends LitElement {
7166

7267
if (declaration === undefined || declaration.kind !== 'class') {
7368
return html`
74-
<wco-top-bar></wco-top-bar>
7569
<div class="full-screen-error">Could not find element declaration</div>
7670
`;
7771
}
@@ -80,7 +74,6 @@ export class WCOElementPage extends LitElement {
8074
const methods = declaration.members?.filter((m) => m.kind === 'method');
8175

8276
return html`
83-
<wco-top-bar></wco-top-bar>
8477
<h1>${packageName}/${elementName}</h1>
8578
<h3>${declaration.summary}</h3>
8679

packages/site-client/src/entrypoints/element-hydrate.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import {renderElementPage} from './element.js';
87
import {hydrate} from 'lit/experimental-hydrate.js';
8+
import {renderBody} from '../templates/body.js';
9+
import {renderElementPage} from './element.js';
910

1011
const data = (
1112
window as unknown as {__ssrData: Parameters<typeof renderElementPage>}
1213
).__ssrData;
13-
hydrate(renderElementPage(...data), document.body);
14+
15+
// We need to hydrate the whole page to remove any defer-hydration attributes.
16+
// We could also remove the attribute manually, or not use deferhydration, but
17+
// instead manually assign the data into the <wco-element-page> element, and
18+
// time imports so that automatic element hydration happend after.
19+
hydrate(renderBody(renderElementPage(...data)), document.body);

packages/site-client/src/entrypoints/homepage.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@
33
* Copyright 2022 Google LLC
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6-
7-
import '../components/wco-top-bar.js';
6+
import 'lit/experimental-hydrate-support.js';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright 2022 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import {html} from 'lit';
8+
import '../components/wco-top-bar.js';
9+
10+
export const renderBody = (content: unknown) => html`<wco-top-bar></wco-top-bar>
11+
${content}`;

packages/site-content/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
},
5555
"build:templates": {
5656
"command": "find templates/src -name \"*.ts\" | xargs esbuild --color --outdir=templates/lib",
57+
"dependencies": [
58+
"../site-client:build"
59+
],
5760
"files": [
5861
"templates/src/**/*.ts"
5962
],
@@ -73,7 +76,8 @@
7376
],
7477
"dependencies": [
7578
"../catalog-api:build",
76-
"../custom-elements-manifest-tools:build"
79+
"../custom-elements-manifest-tools:build",
80+
"../site-client:build"
7781
],
7882
"clean": "if-file-deleted"
7983
},
@@ -90,6 +94,7 @@
9094
},
9195
"dependencies": {
9296
"@11ty/eleventy": "^1.0.2",
97+
"@webcomponents/internal-site-client": "^0.0.0",
9398
"@webcomponents/internal-site-server": "^0.0.0"
9499
}
95100
}

packages/site-content/site/_includes/layouts/base.11ty.cjs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@
66

77
module.exports = {
88
async render(data) {
9-
const {renderPage} = await import('../../../templates/lib/base.js');
10-
// TODO (justinfagnani): move the top-bar to a real template or
11-
// back into the base template when we enable 11ty / Lit SSR integration
9+
const {renderPage, unsafeHTML} = await import(
10+
'../../../templates/lib/base.js'
11+
);
1212
return [
1313
...renderPage({
1414
...data,
15-
content: `
16-
<wco-top-bar></wco-top-bar>
17-
${data.content}
18-
`,
15+
content: unsafeHTML(data.content),
1916
}),
2017
].join('');
2118
},

packages/site-content/templates/src/base.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,30 @@
33
* Copyright 2022 Google LLC
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6+
7+
// This must be imported before lit
8+
import {
9+
render,
10+
RenderInfo,
11+
} from '@lit-labs/ssr/lib/render-with-global-dom-shim.js';
12+
13+
import type {TemplateResult} from 'lit';
14+
import type {DirectiveResult} from 'lit/directive.js';
15+
import {renderBody} from '@webcomponents/internal-site-client/lib/templates/body.js';
16+
617
import {escapeHTML} from './escape-html.js';
18+
export {unsafeHTML} from 'lit/directives/unsafe-html.js';
719

8-
export function* renderPage(data: {
9-
scripts?: Array<string>;
10-
title?: string;
11-
content: string | Iterable<string>;
12-
initialData?: object;
13-
initScript?: string;
14-
}) {
20+
export function* renderPage(
21+
data: {
22+
scripts?: Array<string>;
23+
title?: string;
24+
content: TemplateResult | DirectiveResult;
25+
initialData?: object;
26+
initScript?: string;
27+
},
28+
options?: Partial<RenderInfo>
29+
) {
1530
yield `<!doctype html>
1631
<html lang="en">
1732
<head>
@@ -55,11 +70,7 @@ export function* renderPage(data: {
5570
</head>
5671
<body>
5772
`;
58-
if (typeof data.content === 'string') {
59-
yield data.content;
60-
} else {
61-
yield* data.content;
62-
}
73+
yield* render(renderBody(data.content), options);
6374

6475
if (data.initialData !== undefined) {
6576
yield `<script>window.__ssrData = ${JSON.stringify(

packages/site-server/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@
5656
"../../tsconfig.base.json",
5757
"src/**/*.ts"
5858
],
59-
"output": [],
59+
"output": [
60+
"tsconfig.tsbuildinfo"
61+
],
6062
"dependencies": [
6163
"../site-client:build:types",
6264
"../site-content:build:templates:types"
@@ -89,6 +91,7 @@
8991
"@types/koa-etag": "^3.0.0",
9092
"@types/koa-static": "^4.0.2",
9193
"@web/dev-server": "^0.1.34",
94+
"@webcomponents/internal-site-content": "^0.0.0",
9295
"koa": "^2.13.4",
9396
"koa-conditional-get": "^3.0.0",
9497
"koa-etag": "^4.0.0",

0 commit comments

Comments
 (0)