Skip to content

Commit

Permalink
allow metadata custom route
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Oct 11, 2024
1 parent fd552c5 commit cf3ce30
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 9 deletions.
11 changes: 9 additions & 2 deletions packages/next/src/build/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ import {
isInternalComponent,
isNonRoutePagesPage,
} from '../lib/is-internal-component'
import { isMetadataRoute } from '../lib/metadata/is-metadata-route'
import {
isMetadataRoute,
isMetadataRouteFile,
} from '../lib/metadata/is-metadata-route'
import { RouteKind } from '../server/route-kind'
import { encodeToBase64 } from './webpack/loaders/utils'
import { normalizeCatchAllRoutes } from './normalize-catchall-routes'
Expand Down Expand Up @@ -267,7 +270,11 @@ export async function createPagesMapping({

let route = pagesType === 'app' ? normalizeMetadataRoute(pageKey) : pageKey

if (isMetadataRoute(route) && pagesType === 'app') {
if (
isMetadataRoute(route) &&
pagesType === 'app' &&
isMetadataRouteFile(pagePath, pageExtensions, true)
) {
const filePath = join(appDir!, pagePath)
const staticInfo = await getPageStaticInfo({
nextConfig: {},
Expand Down
14 changes: 11 additions & 3 deletions packages/next/src/server/dev/hot-reloader-turbopack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import { generateEncryptionKeyBase64 } from '../app-render/encryption-utils-serv
import { isAppPageRouteDefinition } from '../route-definitions/app-page-route-definition'
import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths'
import { getNodeDebugType } from '../lib/utils'
import { isMetadataRouteFile } from '../../lib/metadata/is-metadata-route'
// import { getSupportedBrowsers } from '../../build/utils'

const wsServer = new ws.Server({ noServer: true })
Expand Down Expand Up @@ -936,10 +937,17 @@ export async function createHotReloaderTurbopack(
}

const isInsideAppDir = routeDef.bundlePath.startsWith('app/')
const normalizedAppPage = normalizedPageToTurbopackStructureRoute(
page,
extname(routeDef.filename)
const isEntryMetadataRouteFile = isMetadataRouteFile(
routeDef.filename.replace(opts.appDir || '', ''),
nextConfig.pageExtensions,
true
)
const normalizedAppPage = isEntryMetadataRouteFile
? normalizedPageToTurbopackStructureRoute(
page,
extname(routeDef.filename)
)
: page

const route = isInsideAppDir
? currentEntrypoints.app.get(normalizedAppPage)
Expand Down
15 changes: 13 additions & 2 deletions packages/next/src/server/lib/router-utils/setup-dev-bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ import {
ModuleBuildError,
TurbopackInternalError,
} from '../../dev/turbopack-utils'
import { isMetadataRoute } from '../../../lib/metadata/is-metadata-route'
import {
isMetadataRoute,
isMetadataRouteFile,
} from '../../../lib/metadata/is-metadata-route'
import { normalizeMetadataPageToRoute } from '../../../lib/metadata/get-metadata-route'
import { createEnvDefinitions } from '../experimental/create-env-definitions'
import { JsConfigPathsPlugin } from '../../../build/webpack/plugins/jsconfig-paths-plugin'
Expand Down Expand Up @@ -429,7 +432,15 @@ async function startWatcher(opts: SetupOpts) {
pagesType: isAppPath ? PAGE_TYPES.APP : PAGE_TYPES.PAGES,
})

if (isAppPath && isMetadataRoute(pageName)) {
if (
isAppPath &&
isMetadataRoute(pageName) &&
isMetadataRouteFile(
fileName.replace(appDir!, ''),
nextConfig.pageExtensions,
true
)
) {
const staticInfo = await getPageStaticInfo({
pageFilePath: fileName,
nextConfig: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ import { isAppRouteRoute } from '../../../lib/is-app-route-route'
import { DevAppNormalizers } from '../../normalizers/built/app'
import {
isMetadataRoute,
isMetadataRouteFile,
isStaticMetadataRoute,
} from '../../../lib/metadata/is-metadata-route'
import { normalizeMetadataPageToRoute } from '../../../lib/metadata/get-metadata-route'
import path from '../../../shared/lib/isomorphic/path'

export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvider<AppRouteRouteMatcher> {
private readonly normalizers: {
page: Normalizer
pathname: Normalizer
bundlePath: Normalizer
}
private readonly appDir: string

constructor(
appDir: string,
Expand All @@ -25,6 +28,7 @@ export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvid
) {
super(appDir, reader)

this.appDir = appDir
this.normalizers = new DevAppNormalizers(appDir, extensions)
}

Expand All @@ -43,8 +47,18 @@ export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvid

const pathname = this.normalizers.pathname.normalize(filename)
const bundlePath = this.normalizers.bundlePath.normalize(filename)
const ext = path.extname(filename).slice(1)
const isEntryMetadataRouteFile = isMetadataRouteFile(
filename.replace(this.appDir, ''),
[ext],
true
)

if (isMetadataRoute(page) && !isStaticMetadataRoute(page)) {
if (
isMetadataRoute(page) &&
!isStaticMetadataRoute(page) &&
isEntryMetadataRouteFile
) {
// Matching dynamic metadata routes.
// Add 2 possibilities for both single and multiple routes:
{
Expand All @@ -59,7 +73,7 @@ export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvid
const metadataBundlePath = normalizeMetadataPageToRoute(
bundlePath,
false
) // this.normalizers.bundlePath.normalize(dummyFilename)
)

const matcher = new AppRouteRouteMatcher({
kind: RouteKind.APP_ROUTE,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ReactNode } from 'react'
export default function Root({ children }: { children: ReactNode }) {
return (
<html>
<body>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <p>hello world</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// custom /sitemap route, with xml content
export function GET() {
return new Response(
`<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com</loc>
<lastmod>2021-01-01</lastmod>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
`.trim(),
{
headers: {
'Content-Type': 'application/xml',
},
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { nextTestSetup } from 'e2e-utils'

describe('app-dir - metadata-non-standard-custom-routes', () => {
const { next } = nextTestSetup({
files: __dirname,
})

it('should work with custom sitemap route', async () => {
const res = await next.fetch('/sitemap')
expect(res.status).toBe(200)
expect(res.headers.get('content-type')).toBe('application/xml')
expect(await res.text()).toMatchInlineSnapshot(``)
})
})

0 comments on commit cf3ce30

Please sign in to comment.