-
Notifications
You must be signed in to change notification settings - Fork 1k
/
withWebServer.ts
76 lines (61 loc) · 2.17 KB
/
withWebServer.ts
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
import fs from 'fs'
import path from 'path'
import fastifyStatic from '@fastify/static'
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
import { getPaths } from '@redwoodjs/project-config'
import { loadFastifyConfig } from '../fastify'
import type { WebServerArgs } from '../types'
import { findPrerenderedHtml } from './findPrerenderedHtml'
export const getFallbackIndexPath = () => {
const prerenderIndexPath = path.join(getPaths().web.dist, '/200.html')
// If 200 exists: project has been prerendered
// If 200 doesn't exist: fallback to default index.html
if (fs.existsSync(prerenderIndexPath)) {
return '200.html'
} else {
return 'index.html'
}
}
const withWebServer = async (
fastify: FastifyInstance,
options: WebServerArgs
) => {
const prerenderedFiles = findPrerenderedHtml()
const indexPath = getFallbackIndexPath()
// Serve prerendered HTML directly, instead of the index
prerenderedFiles
.filter((filePath) => filePath !== 'index.html') // remove index.html
.forEach((filePath) => {
const pathName = filePath.split('.html')[0]
fastify.get(`/${pathName}`, (_, reply: FastifyReply) => {
reply.header('Content-Type', 'text/html; charset=UTF-8')
reply.sendFile(filePath)
})
})
const { configureFastify } = loadFastifyConfig()
if (configureFastify) {
await configureFastify(fastify, { side: 'web', ...options })
}
// Serve other non-html assets
fastify.register(fastifyStatic, {
root: getPaths().web.dist,
})
// For SPA routing fallback on unmatched routes
// And let JS routing take over
fastify.setNotFoundHandler(
{},
function (req: FastifyRequest, reply: FastifyReply) {
const requestedExtension = path.extname(req.url)
// If it's requesting some sort of asset, e.g. .js or .jpg files
// Html files should fallback to the index.html
if (requestedExtension !== '' && requestedExtension !== '.html') {
reply.code(404)
return reply.send('Not Found')
}
reply.header('Content-Type', 'text/html; charset=UTF-8')
return reply.sendFile(indexPath)
}
)
return fastify
}
export default withWebServer