Skip to content

Commit 995d9fe

Browse files
committed
feat(docs): setup server-side rendering
1 parent e651ee6 commit 995d9fe

8 files changed

Lines changed: 177 additions & 159 deletions

File tree

docs/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
"@angular/core": "17.x.x",
1010
"@angular/forms": "17.x.x",
1111
"@angular/platform-browser": "17.x.x",
12+
"@angular/platform-server": "17.x.x",
1213
"@angular/router": "17.x.x",
14+
"@angular/ssr": "17.x.x",
15+
"express": "^4.19.2",
1316
"@ng-doc/app": "17.5.5",
1417
"@ng-doc/core": "17.5.5",
1518
"@ng-doc/ui-kit": "17.5.5",
1619
"rxjs": "7.x.x",
1720
"tslib": "2.x.x"
1821
},
19-
"peerDependencies": {
20-
"@ng-doc/generated": "*"
22+
"devDependencies": {
23+
"@types/express": "4.17.14"
2124
}
2225
}

docs/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"outputPath": "dist/docs",
1717
"index": "docs/src/index.html",
1818
"browser": "docs/src/main.ts",
19+
"server": "docs/src/main.server.ts",
1920
"polyfills": ["zone.js"],
2021
"tsConfig": "docs/tsconfig.app.json",
2122
"inlineStyleLanguage": "scss",

docs/server.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* eslint-disable no-console */
2+
import { dirname, join, resolve } from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
5+
import { APP_BASE_HREF } from '@angular/common';
6+
import { CommonEngine } from '@angular/ssr';
7+
import express from 'express';
8+
9+
import bootstrap from './src/main.server';
10+
11+
// The Express app is exported so that it can be used by serverless Functions.
12+
export function app(): express.Express {
13+
const server = express();
14+
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
15+
const browserDistFolder = resolve(serverDistFolder, '../browser');
16+
const indexHtml = join(serverDistFolder, 'index.server.html');
17+
18+
const commonEngine = new CommonEngine();
19+
20+
server.set('view engine', 'html');
21+
server.set('views', browserDistFolder);
22+
23+
// Example Express Rest API endpoints
24+
// server.get('/api/**', (req, res) => { });
25+
// Serve static files from /browser
26+
server.get(
27+
'*.*',
28+
express.static(browserDistFolder, {
29+
maxAge: '1y',
30+
}),
31+
);
32+
33+
// All regular routes use the Angular engine
34+
server.get('*', (req, res, next) => {
35+
const { protocol, originalUrl, baseUrl, headers } = req;
36+
37+
commonEngine
38+
.render({
39+
bootstrap,
40+
documentFilePath: indexHtml,
41+
url: `${protocol}://${headers.host}${originalUrl}`,
42+
publicPath: browserDistFolder,
43+
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
44+
})
45+
.then((html) => res.send(html))
46+
.catch((err) => next(err));
47+
});
48+
49+
return server;
50+
}
51+
52+
function run(): void {
53+
const port = process.env['PORT'] || 4000;
54+
55+
// Start up the Node server
56+
const server = app();
57+
server.listen(port, () => {
58+
console.log(`Node Express server listening on http://localhost:${port}`);
59+
});
60+
}
61+
62+
run();

docs/src/app/app.config.server.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
2+
import { provideServerRendering } from '@angular/platform-server';
3+
4+
import { appConfig } from './app.config';
5+
6+
const config: ApplicationConfig = {
7+
providers: [provideServerRendering()],
8+
};
9+
10+
export const appConfigForServer = mergeApplicationConfig(appConfig, config);

docs/src/app/app.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
withInterceptorsFromDi,
55
} from '@angular/common/http';
66
import { ApplicationConfig } from '@angular/core';
7+
import { provideClientHydration } from '@angular/platform-browser';
78
import { provideAnimations } from '@angular/platform-browser/animations';
89
import { provideRouter, withInMemoryScrolling } from '@angular/router';
910
import {
@@ -16,10 +17,12 @@ import {
1617
providePageSkeleton,
1718
provideSearchEngine,
1819
} from '@ng-doc/app';
20+
// eslint-disable-next-line import/no-extraneous-dependencies
1921
import { NG_DOC_ROUTING, provideNgDocContext } from '@ng-doc/generated';
2022

2123
export const appConfig: ApplicationConfig = {
2224
providers: [
25+
provideClientHydration(),
2326
provideAnimations(),
2427
provideRouter(
2528
NG_DOC_ROUTING,

docs/src/main.server.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* eslint-disable import/no-default-export */
2+
import { ApplicationRef } from '@angular/core';
3+
import { bootstrapApplication } from '@angular/platform-browser';
4+
5+
import { AppComponent } from './app/app.component';
6+
import { appConfigForServer } from './app/app.config.server';
7+
8+
const bootstrap = (): Promise<ApplicationRef> =>
9+
bootstrapApplication(AppComponent, appConfigForServer);
10+
11+
export default bootstrap;

docs/tsconfig.app.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"extends": "../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "../out-tsc/app",
5-
"types": []
5+
"types": ["node"]
66
},
7-
"files": ["src/main.ts"],
7+
"files": ["src/main.ts", "src/main.server.ts", "server.ts"],
88
"include": ["src/**/*.d.ts"]
99
}

0 commit comments

Comments
 (0)