I'm using this approach to have centralized route config in Next.js. I don't have the fully automated solution. Right now I'm writing route configs and links manually to figure out if it works and what are the drawbacks. I believe the automation is the last step to make it completely seamless. ## 1. Define routes in centralized config This is the only file that needs to be wrote manually. ```ts //route.config.ts const routeConfig = { // url: filename inside `pages` '/about': '/about', '/article/:id': '/article', } ``` ## 2. Links and route configs are generated Only imported Links/routes are included in bundle, everything else is stripped down using tree-shaking. Each route is transformed into `routeConfig` and custom `Link` component. `routeConfig` can be used for imperative routing (e.g. `Router.push`), while custom `Link` is used in JSX for declarative routing. ```ts // links.ts // generated from route.config.ts export const about = makeRouteConfig("/about") export const AboutLink = makeLink(about) export const article = makeRouteConfig("/article/:id", "/article") export const ArticleLink = makeLink(article) ``` As a bonus, links can be typechecked: ```ts // links.d.ts interface CustomLinkProps extends LinkProps { params: Params } interface ArticleLinkParams {} declare const ArticleLink = React.ElementType> ``` ## 3. now.json is generated as well ```json { "routes": [ { "src": "/about", "dest": "/about.js" }, { "src": "/article/(?[^/]*)", "dest": "/article.js?id=$id" }, ] } ``` ## 4. Example ```ts // pages/index.ts import { AboutLink, ArticleLink } from "../links" export default () => { } ``` ## Summary ✅ this can be build on top of current Next.js API ✅ centralized route config with minimal footprint in bundle ✅ global server handler is used only for development. Pages in production can be served in serverless fashion. 🚫 requires extra compile step to prepare `now.json` and `links.ts` ## Implementation details ### `makeRouteConfig` Little helper to create routeConfig object. ```ts export interface RouteConfig { path: string as: string } export function makeRouteConfig(as: string, path?: string): RouteConfig { if (process.env.NODE_ENV !== "production") { if (!as.startsWith("/")) { throw Error(`path ${as} should start with /`) } } return { as, path: path != null ? path : as } } ``` ### `makeLink` Factory to make custom `Link` with `href` and `as` attributes filled automatically based on `routeConfig` object ```ts import * as React from "react" import Link, { LinkProps } from "next/link" import { reverse, RouteConfig } from "accent/core/routes" export interface RouteLinkProps extends LinkProps { params?: { [key: string]: string } } // Create customized Link component, which fills `href` and `as` props based on routeConfig export const makeLink = (routeConfig: RouteConfig) => ({ params, children, ...linkProps }: RouteLinkProps) => { const href = { pathname: routeConfig.path, query: params } const as = params == null ? routeConfig.as : reverse(routeConfig, params) return ( {children} ) } ```