sitegen/framework/meta/nextjs/is-metadata-route.ts
chloe caruso af60d1172f i accidentally deleted the repo, but recovered it. i'll start committing
it was weird. i pressed delete on a subfolder, i think one of the
pages.off folders that i was using. and then, suddenly, nvim on windows
7 decided to delete every file in the directory. they weren't shred off
the space time continuum, but just marked deleted. i had to pay $80 to
get access to a software that could see them. bleh!

just seeing all my work, a little over a week, was pretty heart
shattering. but i remembered that long ago, a close friend said i could
call them whenever i was feeling sad. i finally took them up on that
offer. the first time i've ever called someone for emotional support.
but it's ok. i got it back. and the site framework is better than ever.

i'm gonna commit and push more often. the repo is private anyways.
2025-06-06 23:38:02 -07:00

136 lines
3.9 KiB
TypeScript

export const STATIC_METADATA_IMAGES = {
icon: {
filename: "icon",
extensions: ["ico", "jpg", "jpeg", "png", "svg"],
},
apple: {
filename: "apple-icon",
extensions: ["jpg", "jpeg", "png"],
},
favicon: {
filename: "favicon",
extensions: ["ico"],
},
openGraph: {
filename: "opengraph-image",
extensions: ["jpg", "jpeg", "png", "gif"],
},
twitter: {
filename: "twitter-image",
extensions: ["jpg", "jpeg", "png", "gif"],
},
} as const;
// Match routes that are metadata routes, e.g. /sitemap.xml, /favicon.<ext>, /<icon>.<ext>, etc.
// TODO-METADATA: support more metadata routes with more extensions
const defaultExtensions = ["js", "jsx", "ts", "tsx"];
const getExtensionRegexString = (extensions: readonly string[]) =>
`(?:${extensions.join("|")})`;
// When you only pass the file extension as `[]`, it will only match the static convention files
// e.g. /robots.txt, /sitemap.xml, /favicon.ico, /manifest.json
// When you pass the file extension as `['js', 'jsx', 'ts', 'tsx']`, it will also match the dynamic convention files
// e.g. /robots.js, /sitemap.tsx, /favicon.jsx, /manifest.ts
// When `withExtension` is false, it will match the static convention files without the extension, by default it's true
// e.g. /robots, /sitemap, /favicon, /manifest, use to match dynamic API routes like app/robots.ts
export function isMetadataRouteFile(
appDirRelativePath: string,
pageExtensions: string[],
withExtension: boolean,
) {
const metadataRouteFilesRegex = [
new RegExp(
`^[\\\\/]robots${
withExtension
? `\\.${getExtensionRegexString(pageExtensions.concat("txt"))}`
: ""
}`,
),
new RegExp(
`^[\\\\/]sitemap${
withExtension
? `\\.${getExtensionRegexString(pageExtensions.concat("xml"))}`
: ""
}`,
),
new RegExp(
`^[\\\\/]manifest${
withExtension
? `\\.${
getExtensionRegexString(
pageExtensions.concat("webmanifest", "json"),
)
}`
: ""
}`,
),
new RegExp(`^[\\\\/]favicon\\.ico$`),
// TODO-METADATA: add dynamic routes for metadata images
new RegExp(
`[\\\\/]${STATIC_METADATA_IMAGES.icon.filename}${
withExtension
? `\\.${
getExtensionRegexString(
pageExtensions.concat(STATIC_METADATA_IMAGES.icon.extensions),
)
}`
: ""
}`,
),
new RegExp(
`[\\\\/]${STATIC_METADATA_IMAGES.apple.filename}${
withExtension
? `\\.${
getExtensionRegexString(
pageExtensions.concat(STATIC_METADATA_IMAGES.apple.extensions),
)
}`
: ""
}`,
),
new RegExp(
`[\\\\/]${STATIC_METADATA_IMAGES.openGraph.filename}${
withExtension
? `\\.${
getExtensionRegexString(
pageExtensions.concat(
STATIC_METADATA_IMAGES.openGraph.extensions,
),
)
}`
: ""
}`,
),
new RegExp(
`[\\\\/]${STATIC_METADATA_IMAGES.twitter.filename}${
withExtension
? `\\.${
getExtensionRegexString(
pageExtensions.concat(STATIC_METADATA_IMAGES.twitter.extensions),
)
}`
: ""
}`,
),
];
return metadataRouteFilesRegex.some((r) => r.test(appDirRelativePath));
}
/*
* Remove the 'app' prefix or '/route' suffix, only check the route name since they're only allowed in root app directory
* e.g.
* /app/robots -> /robots
* app/robots -> /robots
* /robots -> /robots
*/
export function isMetadataRoute(route: string): boolean {
let page = route.replace(/^\/?app\//, "").replace(/\/route$/, "");
if (page[0] !== "/") page = "/" + page;
return (
!page.endsWith("/page") &&
isMetadataRouteFile(page, defaultExtensions, false)
);
}