Repository navigation
Expand file tree
/
Copy pathserver.ts
More file actions
154 lines (117 loc) · 4.28 KB
/
Copy pathserver.ts
File metadata and controls
154 lines (117 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import {APP_BASE_HREF} from '@angular/common';
import {CommonEngine} from '@angular/ssr/node';
import express from 'express';
import {fileURLToPath} from 'node:url';
import {dirname, join, resolve} from 'node:path';
import bootstrap from './src/main.server';
import {SitemapStream} from "sitemap";
import {routes} from "./src/app/app.routes";
import {Routes} from "@angular/router";
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
server.disable('x-powered-by');
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');
let allowedHosts = process.env["DEVELOPMENT_SERVER"] ? ['localhost', '127.0.0.1'] : [process.env["HOSTNAME"] ?? ""]
const commonEngine = new CommonEngine({allowedHosts: allowedHosts});
server.set('view engine', 'html');
server.set('views', browserDistFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('**', express.static(browserDistFolder, {
maxAge: '1y',
index: 'index.html',
}));
//SEO optimization robots
//TODO replace with false for deployment.
let developmentServer = process.env['DEVELOPMENT_SERVER'] === "true"
//TODO replace with your domain.
let hostName = developmentServer ? "http://localhost" : "https://domain.my"
//TODO configure with your Robots.txt content.
//The robots.txt file could also be hosted statically by placing it directly in the public folder. If you still prefer to have two different robots.txt files for the deployment and non-deployment phases, you can ignore this message.
const indexableRobotsContent = developmentServer ?
`User-agent: *
Disallow: /` :
`sitemap: ${hostName}/sitemap.xml
User-agent: *
Disallow: /api/
Disallow: /assets/`;
server.get('/robots.txt', (req, res) => {
res.type('text/plain');
res.send(indexableRobotsContent);
});
//SEO optimization sitemap
var apicache = require('apicache')
var cache = apicache.middleware
server.get('/sitemap.xml', cache('1 hour'), (req, res) => {
res.header('Content-Type', 'application/xml');
try {
const smStream = new SitemapStream({hostname: hostName});
(async () => {
const getPaths = (routes: Routes): string[] => {
let paths: string[] = [];
for (const route of routes) {
if (route.path !== "**") {
if (route.path !== undefined) {
paths.push(route.path);
}
let ch = [{ch: route.children, parent: route.path}]
while (ch && ch.length > 0) {
let tmp = [];
for (let r of ch) {
if (r.ch)
for (let s of r.ch) {
paths.push(`${r.parent}/${s.path}`);
if (s.children) {
tmp.push({ch: s.children, parent: `${r.parent}/${s.path}`});
}
}
}
ch = tmp;
}
}
}
return paths;
};
const routeS = getPaths(routes);
for (const route of routeS) {
smStream.write(route);
}
smStream.end();
smStream.pipe(res).on('error', (e) => {
throw e;
});
})();
} catch (e) {
console.error(e);
res.status(500).end();
}
});
// All regular routes use the Angular engine
server.get('**', (req, res, next) => {
const {protocol, originalUrl, baseUrl, headers} = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [{provide: APP_BASE_HREF, useValue: baseUrl}],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();