Reputation: 21
I am facing a peculiar issue with my Next.js application. The problem appears only in the production environment. In the development environment, everything works fine, but in production, I encounter a client-side exception and 404 errors for some static chunks.
In the production environment, I get the following error: Application error: a client-side exception has occurred (see the browser console for more information).
The browser console shows:
GET https://starblogs-trial.in/_next/static/chunks/app/posts/%5Bslug%5D/page-9f2de8d9ba04381a.js 404 (Not Found) ChunkLoadError: Loading chunk 333 failed. (error: https://starblogs-trial.in/_next/static/chunks/app/posts/%5Bslug%5D/page-9f2de8d9ba04381a.js) at l.f.j (webpack-84ef18324f9abbfd.js:1:3428) at webpack-84ef18324f9abbfd.js:1:1427 at Array.reduce () at l.e (webpack-84ef18324f9abbfd.js:1:1393) at self.next_chunk_load (596-6aee3da8cc55e0f0.js:1:5775) at 596-6aee3da8cc55e0f0.js:9:5750 at 596-6aee3da8cc55e0f0.js:9:5973 at t (596-6aee3da8cc55e0f0.js:9:6176)
In the development environment, everything works perfectly. When I click on a blog post, the data is fetched from the database and displayed correctly. In production, the server logs indicate that the data is fetched correctly, but when trying to access certain properties, the application crashes.
data looks like:
{
"id": "sdfsdfsdfsd3623423432r5b327quqz8",
"createdAt": "2024-06-27T13:11:36.112Z",
"slug": "beautiful-places",
"title": "Beautiful places",
"desc": "<p>Contrary to popular belief, Lorem Ipsum is not simply random text...</p>",
"img": "https://firebasestorage.googleapis.com/v0/b/.........",
"views": 167,
"catSlug": "travel",
"userEmail": "[email protected]",
"user": {
"id": "sdfsdfsdfsd3623423432r5b327quqz8",
"name": "John Doe",
"email": "[email protected]",
"emailVerified": null,
"image": "https://lh3.googleusercontent.com/....."
}
}
src └── app └── posts └── [slug] └── page.jsx
import React from 'react'
import styles from './singlePage.module.css'
import Image from 'next/image'
import Comments from '@/components/comments/Comments'
import Menu from '@/components/menu/Menu'
import DOMPurify from 'isomorphic-dompurify'
const getData = async (slug) => {
const res = await fetch(`${process.env.NEXTAUTH_URL}/api/posts/${slug}`, {
cache: 'no-store',
})
if (!res.ok) {
throw new Error('Failed')
}
return res.json()
}
const SinglePage = async ({ params }) => {
const { slug } = params
let data = null
try {
data = await getData(slug)
} catch (error) {
console.error('Error fetching post data:', error)
}
return (
<div className={styles.container}>
<div className={styles.infoContainer}>
<div className={styles.textContainer}>
<h1 className={styles.title}>{data?.title}</h1>
<div className={styles.user}>
{data?.user?.image && (
<div className={styles.userImageContainer}>
{/* <Image
src={data.user.image}
alt="user image"
fill
className={styles.avatar}
/> */}
</div>
)}
<div className={styles.userTextContainer}>
<span className={styles.username}>{data?.user?.name}</span>
<span className={styles.date}>{data?.createdAt}</span>
</div>
</div>
</div>
{data?.img && (
<div className={styles.imageContainer}>
{/* <Image src={data.img} alt="" fill className={styles.image} /> */}
</div>
)}
</div>
<div className={styles.content}>
<div className={styles.post}>
<div
className={styles.description}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(data?.desc),
}}
/>
<div className={styles.comment}>
{/* <Comments postSlug={slug} /> */}
</div>
</div>
{/* <Menu /> */}
</div>
</div>
)
}
export default SinglePage
The page loads fine when certain parts are commented out in production, Image , Comments and Menu components.
In production, I notice that accessing data?.title, data?.user?.name, data?.createdAt and data?.desc works fine but other properties cause issues in production.
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'lh3.googleusercontent.com',
},
{
protocol: 'https',
hostname: 'firebasestorage.googleapis.com',
},
],
},
env: {
GOOGLE_ID: process.env.GOOGLE_ID,
GOOGLE_SECRET: process.env.GOOGLE_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
DATABASE_URL: process.env.DATABASE_URL,
FIREBASE: process.env.FIREBASE,
},
}
module.exports = nextConfig
I am looking for guidance on the following:
Why does the application work fine in development but fail in production with the mentioned errors?
How can I properly handle the Image , Comments , and Menu components to prevent these client-side exceptions in production? I feel that the problem is not restricted to Image as in Menu component I noticed that even after commenting out Images in menu it still gave erros and my inference was even the links in it might be causing issues.
Any specific configurations I might be missing in next.config.js or elsewhere?
Any help would be greatly appreciated!
Upvotes: 0
Views: 887
Reputation: 11
I encountered the same issue. I hope this helps.
Are you using Nginx as your server? If so, the problem lies in the /%5Bslug%5D/
part of the app router. Usually, the [slug]
portion in links (written as /%5Bslug%5D/
) cannot be read by Nginx, resulting in 503 or 404 errors.
Solution 1: Add a redirect in next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
async redirects() {
return [
{
source: '/_next/static/chunks/app/%5Bslug%5D/:path*',
destination: '/_next/static/chunks/app/[slug]/:path*',
},
]
},
}
module.exports = nextConfig
This redirects the encoded URL to a converted link where: "%5B" → "[" "%5D" → "]"
Solution 2: If it's not a static site, add a redirect in middleware.ts (recommended)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const url = request.nextUrl.clone()
if (url.pathname.includes('/_next/static/chunks/app/')) {
const decodedPathname = decodeURIComponent(url.pathname)
if (url.pathname !== decodedPathname) {
url.pathname = decodedPathname
return NextResponse.rewrite(url)
}
}
return NextResponse.next()
}
export const config = {
matcher: [
'/_next/static/chunks/app/:path*'
]
}
This solution performs the redirect internally, making it robust against page reloads.
By using NextResponse.rewrite(url)
, you can internally rewrite the URL.
I hope this solves your problem!
Upvotes: 1