1
votes

pages/_middleware.ts

import { NextRequest, NextResponse } from 'next/server';

const isMobile = (userAgent: string) =>
  /iPhone|iPad|iPod|Android/i.test(userAgent);

const propName = 'x-rewrite';

enum Device {
  desktop = 'no',
  mobile = 'yes',
}

export function middleware(req: NextRequest) {
  const userAgent = req.headers.get('user-agent');

  const res = NextResponse.next();

  if (userAgent) {
    if (isMobile(userAgent)) {
      res.headers.set(propName, Device.mobile);
      console.log(res.headers, 'res');
      return res;
    } else {
      res.headers.set(propName, Device.desktop);
      return res;
    }
  }
}

next.config.js

async rewrites() {
    return {
      beforeFiles: [
        {
          source: '/football/livescore',
          destination: '/football/livescore/mobile',
          has: [
            {
              type: 'header',
              key: 'x-rewrite',
              value: '(?<rewrite>yes|true)',
            },
          ],
        },
        {
          source: '/football/livescore/:league',
          destination: '/football/livescore/mobile/:league',
          has: [
            {
              type: 'header',
              key: 'x-rewrite',
              value: '(?<rewrite>yes|true)',
            },
          ],
        },
      ],
    };
  },

https://github.com/vercel/next.js/discussions/37841 here, I've opened discussion where I described my issue. I try to rewrite my page (change destination) by header type , but it seems like doesn't work. I see my value in headers , when I check headers on browser, but it doesn't work.

1
Why not rewrite directly from the middleware with NextResponse.rewrite rather than just setting the header?juliomalves
omg , I didn't know it is possible ... thank you a lot , super helpfulAndrey Radkevich

1 Answers

0
votes

Rather than setting the header in the middleware and using rewrites in next.config.js, you can rewrite directly to the mobile path with NextResponse.rewrite from the middleware itself.

import { NextRequest, NextResponse } from 'next/server';

const livescorePath = '/football/livescore';
const mobilePath = '/mobile'

const isMobile = (userAgent: string) => /iPhone|iPad|iPod|Android/i.test(userAgent);

export function middleware(req: NextRequest) {
    const { pathname } = req.nextUrl;
    const userAgent = req.ua?.ua ?? '';

    // Checks if path begins with `/football/livescore` and has mobile UA, 
    // then rewrites to mobile path if so
    if (pathname.startsWith(livescorePath) && !pathname.includes(mobilePath) && isMobile(userAgent)) {
        const league = pathname.replace(livescorePath, '');
        req.nextUrl.pathname = `${livescorePath}${mobilePath}${league}`;
        return NextResponse.rewrite(req.nextUrl);
    }

    return NextResponse.next();
}