Skip to content

Instantly share code, notes, and snippets.

@arekbartnik
Forked from tomhicks/InternalLink.tsx
Created July 19, 2022 07:42
Show Gist options
  • Save arekbartnik/bd367f15ef621f73fc42eb8e06c54977 to your computer and use it in GitHub Desktop.
Save arekbartnik/bd367f15ef621f73fc42eb8e06c54977 to your computer and use it in GitHub Desktop.
Strongly-typed NextJS internal links
const glob = require("glob")
const fs = require("fs")
const prettier = require("prettier")
const basePath = "src/app/pages"
glob(`${basePath}/**/*.{tsx,ts}`, undefined, (err, files) => {
const pageFiles = files
.map(f =>
f
.replace(basePath, "")
.replace(/\.\w+$/, "")
.replace(/\/index$/, ""),
)
.filter(f => !f.startsWith("/_"))
.map(file => {
const paramNames = (file.match(/\[\w+\]/g) || []).map(pathSegment =>
pathSegment.replace(/[\[\]]/g, ""),
)
return {
routeName: file,
routeParams: paramNames,
}
})
const allTypes = pageFiles.map(typeTemplate)
fs.writeFileSync(
"src/app/types/routes.ts",
prettier.format(
`
export type InternalRoutes = | ${allTypes.join("\n| ")}
`,
{
semi: false,
parser: "typescript",
},
),
)
})
const typeTemplate = ({routeName, routeParams}) => `{
routeName: "${routeName}";
routeParams${routeParams.length ? "" : "?"}: {
${routeParams.map(param => `${param}: string`).join(";\n ")}
}
}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment