Skip to content

Commit ebfa78e

Browse files
committed
SSR: serve prerendered page to crawlers
1 parent dbd0eb4 commit ebfa78e

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

server.mjs

+34-16
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ async function ssr(url, {useCache = true, onlyCriticalRequests = true,
126126
page.on('response', async resp => {
127127
const href = resp.url();
128128
const type = resp.request().resourceType();
129-
const sameOriginResource = href.startsWith(url);
129+
const sameOriginResource = new URL(href).origin === new URL(url).origin;
130130
// Only inline local resources.
131131
if (sameOriginResource) {
132132
if (type === 'stylesheet') {
@@ -199,6 +199,25 @@ async function ssr(url, {useCache = true, onlyCriticalRequests = true,
199199
return html;
200200
}
201201

202+
async function doSSR(url, req) {
203+
// This ignores other query params on the URL besides the tweets.
204+
url = new URL(url);
205+
if ('tweets' in req.query) {
206+
url.searchParams.set('tweets', '');
207+
}
208+
209+
const html = await ssr(url.href, {
210+
useCache: 'nocache' in req.query ? false : true,
211+
inlineStyles: 'noinline' in req.query ? false : true,
212+
inlineScripts: 'noinline' in req.query ? false : true,
213+
onlyCriticalRequests: 'noreduce' in req.query ? false : true,
214+
reuseChrome: 'reusechrome' in req.query ? true : false,
215+
headless: 'noheadless' in req.query ? false : true,
216+
});
217+
218+
return html;
219+
}
220+
202221
dbHelper.setApp(firebasedAdmin.initializeApp({
203222
// credential: firebasedAdmin.credential.applicationDefault()
204223
credential: firebasedAdmin.credential.cert(
@@ -229,6 +248,19 @@ app.use(function addRequestHelpers(req, res, next) {
229248

230249
// app.use(bodyParser.urlencoded({extended: true}));
231250
app.use(bodyParser.json());
251+
252+
// Handle index.html page dynamically.
253+
app.get('/', async (req, res, next) => {
254+
// Server prerendered page to search crawlers.
255+
if (req.get('User-Agent').match(/googlebot|bingbot/i)) {
256+
const html = await doSSR(`${req.getOrigin()}/index.html`, req);
257+
// res.append('Link', `<${url}/styles.css>; rel=preload; as=style`); // Push styles.
258+
return res.status(200).send(html);
259+
}
260+
next();
261+
});
262+
263+
232264
app.use(express.static('public', {extensions: ['html', 'htm']}));
233265
app.use(express.static('node_modules'));
234266
// app.use(express.static('node_modules/firebase'));
@@ -275,21 +307,7 @@ app.use(express.static('node_modules'));
275307
// SSR render, 3G Slow:
276308
// FP/FCP: 2.3s, 8.37s faster!
277309
app.get('/ssr', catchAsyncErrors(async (req, res) => {
278-
// This ignores other query params on the URL besides the tweets.
279-
const url = new URL(req.getOrigin());
280-
if ('tweets' in req.query) {
281-
url.searchParams.set('tweets', '');
282-
}
283-
284-
const html = await ssr(url.href, {
285-
useCache: 'nocache' in req.query ? false : true,
286-
inlineStyles: 'noinline' in req.query ? false : true,
287-
inlineScripts: 'noinline' in req.query ? false : true,
288-
onlyCriticalRequests: 'noreduce' in req.query ? false : true,
289-
reuseChrome: 'reusechrome' in req.query ? true : false,
290-
headless: 'noheadless' in req.query ? false : true,
291-
});
292-
// res.append('Link', `<${url}/styles.css>; rel=preload; as=style`); // Push styles.
310+
const html = await doSSR(`${req.getOrigin()}/index.html`, req);
293311
res.status(200).send(html);
294312
}));
295313

0 commit comments

Comments
 (0)