skip to Main Content

I’m using Next.JS 14, I want to show a page to the client if the request is coming from a browser but if it’s not from a browser redirect to another website.
Base on this code section I’ve done the redirect part but there isn’t any documentation for showing the page.
I’d appreciate if you can help me out how to show the page.
Thanks.

// for GET method 
export async function GET(request) {
    const headersList = headers();
    if(!headersList.get("Accept").includes("text/html")) {
        return NextResponse.redirect("https://example.com");
    }
    
    return Page(); //LAYOUT
}

2

Answers


  1. By checking Header, secFetchSite, secFetchMode, userAgent we can confirm if the request is from browser

    import { headers } from 'next/headers'
    import { redirect } from 'next/navigation'
    import ClientComponentfrom './ClientComponent'
    
    const headersList = headers()
      
      // get relevant headers
      const userAgent = headersList.get('user-agent')?.toLowerCase() || ''
      const acceptHeader = headersList.get('Accept') || ''
      const secFetchMode = headersList.get('Sec-Fetch-Mode')
      const secFetchSite = headersList.get('Sec-Fetch-Site')
      
      // browser detection logic
      const isBrowser = 
        // check if it's a common browser user-agent
        (userAgent.includes('mozilla/') || userAgent.includes('chrome/') || 
         userAgent.includes('safari/') || userAgent.includes('edge/') ||
         userAgent.includes('firefox/')) &&
        // modern browsers send these security headers
        secFetchMode === 'navigate' &&
        // should be from same-origin or none (direct navigation)
        (secFetchSite === 'same-origin' || secFetchSite === 'none') &&
        // Should accept HTML
        acceptHeader.includes('text/html')
    
      // if not a browser, redirect
      if (!isBrowser) {
        return NextResponse.redirect('https://abcxyz.com.io')
      }
    
      return (
        <main className="p-4">
          <h1>Welcome</h1>
          {/* your client component will render here */}
          <ClientComponent />
        </main>
      )
    }
    
    Login or Signup to reply.
  2. While the previous answer should work, if performance is a concern you can also try setting up a middleware by creating a middleware.js file at the root of your project.

    So for instance the middleware file should look something like the following:

    import { NextResponse } from 'next/server';
    
    export function middleware(request) {
      const acceptHeader = request.headers.get('accept') || '';
    
      if (!acceptHeader.includes('text/html')) {
        return NextResponse.redirect('https://example.com');
      }
    
      // Proceed to render the page as usual
      return NextResponse.next();
    }
    

    Plus a config object if you want to limit to specific paths
    export const config = { matcher: '/your-specific-path/:path*' };

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search