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 ofapp.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
