NextJs Update from 13 to 15
Guide: Updating storefront-starter-kit from Next.js 13 to Next.js 15
storefront-starter-kit from Next.js 13 to Next.js 15This guide outlines the steps to upgrade storefront-starter-kit to Next.js 15, including updating dependencies, migrating routing logic, and aligning environment variable handling to match Next.js's built-in mechanisms.
1. Update Dependencies
Begin by upgrading your dependencies to ensure compatibility with Next.js 15:
npm i next@^15 react@^18 react-dom@^18 eslint-config-next@^152. Aligning Environment Variables
Previous Approach: dotenv-webpack
dotenv-webpackIn older versions, your project might use dotenv-webpack to read .env files and make environment variables accessible in both server and client-side code. For example:
webpack: (config) => {
config.plugins = config.plugins || [];
config.plugins = [
...config.plugins,
// Read the .env file
new Dotenv({
path: path.join(__dirname, '.env'),
systemvars: true,
}),
];
return config;
},Why Change?
-
Conflicts in Next.js 15:
Thedotenv-webpackplugin conflicts with Next.js 15's middleware system, causing issues such as:- Middleware not functioning correctly.
- Unexpected behavior during runtime.
-
Native Next.js Support:
Next.js now provides a robust way to handle environment variables without external plugins.
New Approach: Use Next.js .env Conventions
.env Conventions-
Remove the
dotenv-webpackplugin configuration fromnext.config.js. -
Rename your
.envvariables to align with Next.js conventions:- Public Variables: Prefix with
NEXT_PUBLIC_to make them accessible in client-side code. - Private Variables: Do not prefix with
NEXT_PUBLIC_to restrict them to server-side code.
- Public Variables: Prefix with
Example .env Update:
.env Update:Before:
API_URL=https://api.example.com
SECRET_KEY=my-secret-keyAfter:
NEXT_PUBLIC_API_URL=https://api.example.com
SECRET_KEY=my-secret-keyImportant Notes:
- Restart the development server after modifying
.env. - Public variables (
NEXT_PUBLIC_*) will automatically be accessible on both the client and server. - Private variables will remain server-side only.
3. Standard Routing: Replace app.render with rewrites()
app.render with rewrites()In your server/index.js, you might find routing logic like this:
server.get('/pali', (req, res) => {
app.render(req, res, '/library/entry', req.query);
});Action: Use rewrites() Instead
rewrites() Instead- Remove the route from
server/index.js. - Add a rewrite rule in
next.config.js:
module.exports = {
async rewrites() {
return [
{
source: '/pali',
destination: '/library/entry',
},
];
},
};4. Wildcard Dynamic Routing
For dynamic routing where all paths redirect to a specific page, replace this logic in server/index.js:
server.get(/^(.*)$/, (req, res) => {
app.render(req, res, '/frontend/entry', {
seoUrl: req.params[0],
...req.query,
});
});Step 1: Add Middleware
Create a middleware.js file in the root of your project:
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req) {
const pathname = req.nextUrl.pathname;
// Match all paths using a wildcard pattern
const pattern = /^(.*)$/;
if (pattern.test(pathname)) {
const url = req.nextUrl.clone();
// Set `seoUrl` parameter based on the pathname
const seoUrl = url.pathname;
url.searchParams.set('seoUrl', seoUrl);
// Preserve existing query parameters
req.nextUrl.searchParams.forEach((value, key) => {
url.searchParams.set(key, value);
});
// Rewrite the request to /frontend/entry
return NextResponse.rewrite(url);
}
return NextResponse.next();
}Step 2: Add a Wildcard Rewrite innext.config.js
next.config.jsUpdate the rewrites() function to include a wildcard rule:
module.exports = {
async rewrites() {
return [
{
source: '/pali', // Example standard route
destination: '/library/entry',
},
{
source: '/:path*', // Wildcard for all other paths
destination: '/frontend/entry',
},
];
},
};5. Remove Legacy Code
Delete Routing in server/index.js
server/index.jsRemove any app.render logic, including both standard routes and wildcard handlers:
server.get('/pali', (req, res) => {
app.render(req, res, '/library/entry', req.query);
});
server.get(/^(.*)$/, (req, res) => {
app.render(req, res, '/frontend/entry', {
seoUrl: req.params[0],
...req.query,
});
});6. Test Your Application
-
Restart the Development Server
Start the app with:npm run dev -
Verify Environment Variables
Test public and private variables:- Log
process.env.NEXT_PUBLIC_API_URLin client-side code. - Log
process.env.SECRET_KEYin server-side code.
- Log
-
Verify Routing
- Test
/palito ensure it rewrites to/library/entry. - Test wildcard routes like
/exampleto confirm they rewrite to/frontend/entrywithseoUrland query parameters.
- Test
Why Migrate?
Environment Variables
- Conflict Resolution: Removing
dotenv-webpackresolves conflicts that break Middleware in Next.js 15. - Native Support: Next.js provides first-class support for
.envhandling without additional configuration.
Routing
- Deprecation of
app.render: Next.js 15 fully adopts the App Router, making custom server routing obsolete. - Performance: Middleware operates at the edge, reducing latency for dynamic routes.
By following this guide, your storefront-starter-kit will be fully compatible with Next.js 15, adhering to its best practices for environment variables, routing, and middleware.
Updated about 2 months ago
