Any other language in programming than English looks very weird
A function named powiekszPierwszaLitere
or a folder called o-nas
will hurt my eyes. But very often, I make websites for my Poland brotherhood, and of course, content is better in the local language.
In Next.js, folder names are also the path names. The easiest way is to name the folder exactly how the root should look, but as we said earlier, it’s terrible. In this tutorial, I’ll show you how to do this in an easy way that’s also good for SEO. Let’s go!
Rewrites
Next.js provides us with a function called Rewrites()
. As the name suggests, it maps one URL address to another. In our case, it translates Polish URLs into English.
For example, the function returns an array with two objects, each containing two keys.
- The first key is
source
– this is the URL the user sees in the browser.
// next.config.ts
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/galeria',
destination: '/gallery',
},
{
source: '/kontakt',
destination: '/contact',
},
]
},
}
export default nextConfig
It sounds good, but we have a little problem. We now have two routes, two paths for the same page. We want to use only /kontakt
, but we end up with both /kontakt
and /contact
. That’s not a good idea. But maybe we could redirect the English path to the Polish one, and everything will be great?
Redirects
Next.js gives us another function called Redirects()
. This function, as expected, redirects from one path to another. These two functions are very similar, but there’s a key difference:
-
Rewrites()
changes the URL that the user sees in the browser, while -
Redirects()
simply... redirects.
For example, Redirects()
returns an array of objects, but this time with three keys:
- The first key,
source
, is the URL the user sees in the browser. - The second key,
destination
, is the URL where Next.js will redirect the request. - The third key,
permanent
, is a boolean. If we want a 301 (permanent redirect), we set it totrue
. For a 307 (temporary redirect), we set it tofalse
.
Looks good – maybe, in combination, these two functions will give us the desired outcome.
// next.config.ts
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/galeria',
destination: '/gallery',
},
{
source: '/kontakt',
destination: '/contact',
},
]
},
async redirects() {
return [
{
source: '/gallery',
destination: '/galeria',
permanent: true,
},
{
source: '/kontakt',
destination: '/contact',
permanent: true,
},
]
},
}
export default nextConfig
It’s working! It looks like everything is good. But there’s a small problem. When we pass /contact
, we get redirected. That’s what we want, but we don’t actually have this page in our app. Instead, we want to return a notFound
page. Alright, let’s do this!
Middleware
This time we will use a function called Middleware()
. It’s a special function that operates between the client’s request and the server’s response.
- It allows you to execute logic, modify requests, or redirect users before they reach a specific page.
- It works globally or on selected routes, meaning it can intercept any request and decide what to do with it.
We create this script in the main folder of the Next.js structure.
// middleware.ts
import { NextResponse, type NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
if (pathname === '/contact') {
return NextResponse.rewrite(new URL('/404', request.url))
}
return NextResponse.next()
We import NextResponse
; this object is responsible for handling Next.js requests, while NextRequest
represents the incoming HTTP request. They contain information such as the URL, headers, etc.
We export the middleware
function, where the argument is a request of type NextRequest
. Next, we destructure pathname
from request.nextUrl
to get the path after the domain.
We check the statement to see if the pathname
equals, in our case, /contact
. If that's true, we rewrite this request to redirect to the 404 page.
And that’s it!
// next.config.ts
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/galeria',
destination: '/gallery',
},
{
source: '/kontakt',
destination: '/contact',
},
]
},
// async redirects() {
// return [
// {
// source: '/gallery',
// destination: '/galeria',
// permanent: true,
// },
// {
// source: '/contact',
// destination: '/kontakt',
// permanent: true,
// },
// ]
// },
}
export default nextConfig
// middleware.ts
import { NextResponse, type NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
if (pathname === '/contact') {
return NextResponse.rewrite(new URL('/404', request.url))
}
return NextResponse.next()
}
Bonus
And for the end, a little bonus. What if we want to change the pathname, but after that, we have something like /blog/[slug]
? It’s very easy, and I’ll show you how!
//next.config.ts
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.sanity.io',
},
],
},
async rewrites() {
return [
{
source: '/galeria',
destination: '/gallery',
},
{
source: '/kontakt',
destination: '/contact',
},
{
source: '/aktualnosci',
destination: '/blog',
},
{
source: '/aktualnosci/:slug*',
destination: '/blog/:slug*',
},
]
},
}
export default nextConfig
//middleware.ts
import { NextResponse, type NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
if (pathname === '/gallery' || pathname === '/contact' || pathname === '/blog') {
return NextResponse.rewrite(new URL('/404', request.url))
}
if (pathname.startsWith('/blog/')) {
return NextResponse.rewrite(new URL('/404', request.url))
}
return NextResponse.next()
}
Check YouTube: https://youtu.be/SFAyBM02k9A?si=NivqJGq6cgMfHn_9
Top comments (0)