User-Agent Based Rendering
Sometimes the desktop version of our application differs a lot from our mobile version, because the UI is different or because we load different scripts, styles, etc. We want to decide which page to load based on the User-Agent header without loading unnecesary assets for the current viewport.
Folder structure
We will rewrite our user to different pages based on its User-Agent so we need to have a different page for every viewport we want to support.
The example has a pages/_viewport
folder with pages for mobile
and desktop
, alongside a root middleware (/middleware.js
) that will handle all requests to our pages:
/middleware.ts /pages /_viewport /mobile.tsx /desktop.tsx
Checking the User-Agent
In the middleware, we now check the User-Agent header and rewrite to the correct page:
import { NextRequest, NextResponse, userAgent } from 'next/server'
// Set pathname where middleware will be executed
export const config = {
matcher: '/',
}
export function middleware(req) {
// Parse user agent
const { device } = userAgent(req)
// Check the viewport
const viewport = device.type === 'mobile' ? 'mobile' : 'desktop'
// Update the expected url
req.nextUrl.pathname = `_viewport/${viewport}`
// Return rewrited response
return NextResponse.rewrite(req.nextUrl)
}
Now, everytime a request comes in we will check the User-Agent and rewrite the user to the correct page:
Result
This page is using this strategy, try it out in different devices and you will see the message below changing accordingly:
This page was loaded on a desktop device.