next.js
742a2c78 - next/root-params (#80255)

Commit
151 days ago
next/root-params (#80255) Implements accessing root params (params segments that occur above root layouts) via compiler-generated getters from the `next/root-params` module: ```tsx // app/[lang]/layout.tsx // (there is no app/layout.tsx, this is the root layout) import { lang } from "next/root-params"; // ^^^^ coresponds to the [lang] segment above this module export default async function RootLayout({ children }) { return ( <html lang={await lang()}> <body>{children}</body> </html> ); } ``` - This API is only usable within server components (support for using it in route handlers will be added in the future). It can be called anywhere in the component tree, not just in a page or a layout. - It **cannot be used in server actions**, because they're not tied to a route. - It will replace `unstable_rootParams`, which will be removed soon. Note that we can also have multiple root layouts with distinct params, like this: ``` app/product/[productId]/layout.tsx app/brand/[brandId]/layout.tsx ``` In this case we'll generate getters for both `productId` and `brandId`. They can be called anywhere, but they'll return `undefined` if used in a subtree where a param isn't available. Note that this PR does not yet generate type declarations for the generated getters, essentially leaving them typed as `any`. This will be handled in a follow up. ## Implementation notes ### Turbopack We collect the root param names when analyzing the folder structure in `app_structure.rs`. The set is then passed down (as a Vc) all the way to `next_import_map.rs`, where we insert an alias to a virtual `next/root-params.js` module. We use a `ImportMapping::Dynamic` to generate its code lazily in a separate turbo task (which is the only place that actually reads the root params). This avoids invalidating the whole `ResolveOptionsContext` if the root params change. ### Webpack We alias `next/root-params` to `next-root-params-loader`, which scans the directory structure manually (i haven't found a good way to re-use existing methods for doing this) and returns the generated module. Each directory we traverse before finding a root layout is marked as a `contextDependency`, which should invalidate the loader's result if new files are added to any of them or if they get renamed, because it might mean that the set of root params changed.
Author
Parents
Loading