Create a Next.js project, choose the router that matches the codebase, move shared page chrome into a layout, turn each public URL into a route and convert repeated blocks into components. Replace inline scripts with explicit React behaviour, keep components on the server unless they need browser interaction, migrate metadata and assets, then test every route and form before redirecting traffic.
Reviewed for material changes on August 13, 2026
Choose the project shape before moving files
For a new migration, the App Router is the current Next.js route model and uses folders, layouts and page files. The Pages Router remains supported, so an established Pages project does not need a second migration just to absorb a few HTML pages.
Decide whether the output needs server features, static export or a mix. Forms, authentication, personalised content and frequently changing data may affect that choice. Write the hosting constraint down now; it is painful to discover at the end that a required feature does not fit a fully static deployment.
Move the shell, then create routes one by one
Put the document-wide pieces—fonts, navigation, footer and global styles—into the root layout. Create a page for each existing public path, keeping useful URLs stable. Nested layouts are helpful when a group such as documentation or account pages shares its own navigation.
Copy content into JSX carefully: class becomes className, label relationships stay intact and unclosed tags need closing. Resist the urge to redesign while syntax errors are still moving around. First reach parity; then make deliberate improvements.
Extract repetition without building a component museum
Turn repeated patterns into components and pass their changing content as props. A PricingCard used twelve times is a clear candidate. A one-off ornamental wrapper probably is not.
App Router pages and layouts are Server Components by default. Add the client directive only to the smallest component that needs state, event handlers or browser APIs. That keeps the server-rendered page simple and avoids shipping interaction code for static content.
Give assets and metadata a proper home
Move public files with stable addresses into the public directory, or adopt Next.js image and font tooling where it suits the project. Check dimensions, crop behaviour and loading on a real narrow screen; an image that merely appears is not necessarily migrated well.
In the App Router, use the metadata APIs and special files for titles, descriptions, social images, robots rules and sitemaps. Next.js replaced the old next/head pattern in App Router pages with built-in metadata support. Preserve canonical intent and do not give every route the same description.
Trace every request before launch
Old HTML forms may post to a hosted endpoint, a server script or a marketing platform. Recreate the full contract: field names, validation, bot handling, consent, delivery and success or failure messages. The thank-you state is part of the feature.
Build the production output, visit every generated route and check the network panel for missing files and failed requests. Test with JavaScript slow or unavailable where the page should still read sensibly, then compare Core Web Vitals and analytics events after real traffic reaches the new version.
Sources and checks
Product limits and prices came from the companies themselves:
- Next.js documentation
- Next.js: App Router migration guide
- Next.js: metadata and OG images
- Next.js: static exports
Plans move. We date every check so you know when to verify again.