Skip to content

Instantly share code, notes, and snippets.

@Kavan72
Last active July 3, 2023 06:31
Show Gist options
  • Save Kavan72/bbb99b9eb504b696353c9f70a8666b79 to your computer and use it in GitHub Desktop.
Save Kavan72/bbb99b9eb504b696353c9f70a8666b79 to your computer and use it in GitHub Desktop.
Static Next.js serve on s3 with CloudFront
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'
const TTL = 10000
const S3_REGION = '' // Update this with your s3 region
const S3_BUCKET_NAME = '' // Update this with your s3 bucket name
const S3_FILE_PATH = 'routes-manifest.json'
const s3 = new S3Client({ region: S3_REGION })
const s3Params = {
Bucket: S3_BUCKET_NAME,
Key: S3_FILE_PATH
}
let jsonFile
const pullStream = async body => {
const buffers = []
for await (const chunk of body) {
buffers.push(Buffer.from(chunk))
}
return Buffer.concat(buffers)
}
const getRoutes = async () => {
if (jsonFile) return jsonFile
const response = await s3.send(new GetObjectCommand(s3Params))
jsonFile = JSON.parse(await pullStream(response.Body))
setTimeout(() => (jsonFile = undefined), TTL)
return jsonFile
}
const getOriginPath = async clientPath => {
const { staticRoutes, dynamicRoutes } = await getRoutes()
const staticUserRoute = staticRoutes.find(obj => clientPath.match(obj['regex']))
const dynamicUserRoute = dynamicRoutes.find(obj => clientPath.match(obj['regex']))
let redirectPage
let routeParams
if (staticUserRoute) {
redirectPage = staticUserRoute['page']
} else if (dynamicUserRoute) {
routeParams = {}
const regex = new RegExp(dynamicUserRoute.namedRegex)
const matches = regex.exec(clientPath)
for (const key in dynamicUserRoute.routeKeys) {
const newKey = key.replace('nxtP', '')
routeParams[newKey] = matches.groups[key]
}
redirectPage = dynamicUserRoute.page
for (const param in routeParams) {
redirectPage = redirectPage.replace(`[${param}]`, routeParams[param])
}
} else {
return '/404.html'
}
return redirectPage.endsWith('/') ? `${redirectPage}index.html` : `${redirectPage}/index.html`
}
export const handler = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false
const request = event.Records[0].cf.request
const { uri } = request
console.log(`URI: ${uri}`)
if (uri.indexOf('.') >= 0 || uri === '/') {
request.uri = uri === '/' ? '/index.html' : uri
return callback(null, request)
}
try {
request.uri = await getOriginPath(uri)
console.log(request.uri)
callback(null, request)
} catch (err) {
console.log(err)
callback(null, request)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment