Skip to content

Commit

Permalink
feat: add additional routes to ssr paths
Browse files Browse the repository at this point in the history
  • Loading branch information
orinokai committed Nov 27, 2024
1 parent 47be7cb commit 93b950a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
52 changes: 44 additions & 8 deletions src/build/functions/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,61 @@ const applyTemplateVariables = (template: string, variables: Record<string, stri
}

/** Convert Next.js route syntax to URLPattern syntax */
const transformRoutePattern = (route: string): string => {
const transformRoutePatterns = (route: string): string => {
return route
.replace(/\[\[\.\.\.(\w+)]]/g, ':$1*') // [[...slug]] -> :slug*
.replace(/\[\.{3}(\w+)]/g, ':$1+') // [...slug] -> :slug+
.replace(/\[(\w+)]/g, ':$1') // [id] -> :id
}

/** Get's the content of the handler file that will be written to the lambda */
const getHandlerFile = async (ctx: PluginContext): Promise<string> => {
const templatesDir = join(ctx.pluginDir, 'dist/build/templates')
const getRoutes = async (ctx: PluginContext) => {
const internalRoutes = [
'/_next/static/*',
'/_next/data/*',
'/_next/image/*',
'/_next/postponed/*',
]

const routesManifest = await ctx.getRoutesManifest()
const routes = [...routesManifest.staticRoutes, ...routesManifest.dynamicRoutes]
.map((route) => transformRoutePattern(route.page))
.join("','")
const staticRoutes = routesManifest.staticRoutes.map((route) => route.page)
const dynamicRoutes = routesManifest.dynamicRoutes.map((route) => route.page)

// route.source conforms to the URLPattern syntax, which will work with our redirect engine
// however this will be a superset of possible routes as it does not parse the
// header/cookie/query matching that Next.js offers
const redirects = routesManifest.redirects.map((route) => route.source)
const rewrites = Array.isArray(routesManifest.rewrites)
? routesManifest.rewrites.map((route) => route.source)
: []

// this contains the static Route Handler routes
const appPathRoutesManifest = await ctx.getAppPathRoutesManifest()
const appRoutes = Object.values(appPathRoutesManifest)

// this contains the API handler routes
const pagesManifest = await ctx.getPagesManifest()
const pagesRoutes = Object.keys(pagesManifest)

return [
...internalRoutes,
...staticRoutes,
...dynamicRoutes,
...redirects,
...rewrites,
...appRoutes,
...pagesRoutes,
'/*', // retain the catch-all route for our initial testing
].map(transformRoutePatterns)
}

/** Get's the content of the handler file that will be written to the lambda */
const getHandlerFile = async (ctx: PluginContext): Promise<string> => {
const routes = await getRoutes(ctx)

const templatesDir = join(ctx.pluginDir, 'dist/build/templates')
const templateVariables: Record<string, string> = {
'{{useRegionalBlobs}}': ctx.useRegionalBlobs.toString(),
'{{paths}}': routes,
'{{paths}}': routes.join("','"),
}
// In this case it is a monorepo and we need to use a own template for it
// as we have to change the process working directory
Expand Down
16 changes: 16 additions & 0 deletions src/build/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,22 @@ export class PluginContext {
return JSON.parse(await readFile(join(this.publishDir, 'routes-manifest.json'), 'utf-8'))
}

/**
* Get Next.js app path routes manifest from the build output
*/
async getAppPathRoutesManifest(): Promise<Record<string, string>> {
return JSON.parse(
await readFile(join(this.publishDir, 'app-path-routes-manifest.json'), 'utf-8'),
)
}

/**
* Get Next.js app path routes manifest from the build output
*/
async getPagesManifest(): Promise<Record<string, string>> {
return JSON.parse(await readFile(join(this.publishDir, 'server/pages-manifest.json'), 'utf-8'))
}

#nextVersion: string | null | undefined = undefined

/**
Expand Down

0 comments on commit 93b950a

Please sign in to comment.