#skip assets in middlware
1 messages · Page 1 of 1 (latest)
To skip static assets in your Next.js middleware and avoid issues like unwanted redirects (302) for images, your matcher configuration should ensure that requests for static files (including images, CSS, etc.) are excluded from middleware processing.
The pattern you are using:
export const config = {
matcher: ['/api/:path*', '/((?!_next/static|_next/image|favicon.ico).*)'],
};
is almost correct, but you may still encounter issues if your images are served from the public directory (e.g., /images/foo.jpg) and your middleware is not excluding those paths. This can cause the image optimizer to fail, especially if your middleware performs redirects or authentication checks, as the internal image requests may not have the necessary headers forwarded, resulting in broken images or unexpected redirects Negative matching example Regression: Image optimizer fails to serve images on routes requiring authorization.
Solution:
- Make sure to exclude all relevant static asset paths from your matcher. If your images are in a folder like
/images, add that to your negative lookahead. - Here’s an improved matcher example:
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - images (public images)
*/
'/((?!api|_next/static|_next/image|favicon.ico|images).*)',
],
};
This will ensure that requests to /images/* are not processed by your middleware, preventing unwanted redirects or authentication checks for static assets Regression: Image optimizer fails to serve images on routes requiring authorization.
If you have other static asset folders (e.g., /fonts, /css), add them to the negative lookahead as well.
Summary:
Update your matcher to explicitly exclude all static asset routes you want to skip in middleware. This should resolve the 302 redirect issue for images and ensure they load correctly.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow depot Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@haughty spire how to add import { GoogleAnalytics } from '@next/third-parties/google'in nextjs 14 approuter
Let me check the knowledge base for you again. Give me one moment! :books:
To add Google Analytics using
import { GoogleAnalytics } from '@next/third-parties/google'
in a Next.js 14 App Router project, follow these steps:
-
Install the package
Make sure you have the experimental@next/third-partiespackage installed:npm install @next/third-parties@latest next@latest -
Add the GoogleAnalytics component to your root layout
In yourapp/layout.tsx(or.js), import and use the component, passing your Google Analytics Measurement ID (starts withG-):import { GoogleAnalytics } from '@next/third-parties/google' export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <body> {children} <GoogleAnalytics gaId="G-XXXXXXX" /> </body> </html> ) }Replace
"G-XXXXXXX"with your actual GA4 Measurement ID. -
That's it!
Google Analytics will now be loaded on all routes in your App Router application. You do not need to manually add scripts or handle hydration—this component takes care of it for you.
Note: If you are already using Google Tag Manager, you can configure Google Analytics through it instead of adding both separately How to optimize third-party libraries.
For more details, see the official documentation:
How to optimize third-party libraries > Google Analytics
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow depot Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@haughty spire how to remove search params from the url without needing to refresh, is that poosible nextjs 14 app router
Let me check the knowledge base for you again. Give me one moment! :books:
Yes, in Next.js 14 with the App Router, you can remove search params from the URL without refreshing the page by using the useRouter hook's push or replace methods, or by using the native window.history.replaceState for shallow routing.
Example using useRouter:
'use client'
import { useRouter, usePathname } from 'next/navigation'
export default function RemoveSearchParamsButton() {
const router = useRouter()
const pathname = usePathname()
const handleClick = () => {
// Navigates to the same path without any search params
router.replace(pathname)
}
return <button onClick={handleClick}>Remove Search Params</button>
}
This will update the URL to remove all search parameters without a full page refresh useRouter documentation.
Alternative: Shallow routing with the History API
You can also use the browser's History API for shallow routing:
'use client'
export default function RemoveSearchParamsButton() {
const handleClick = () => {
window.history.replaceState(null, '', window.location.pathname)
}
return <button onClick={handleClick}>Remove Search Params</button>
}
This approach also updates the URL without a refresh and works well for client-only state Shallow routing on the client.
Both methods are supported and do not require a page reload.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow depot Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@haughty spire is this correct in nextjs 14
import type { NextRequest } from 'next/server';
import { env } from '@/env';
import { getAuthenticatedUser } from '../lib/utils';
export const GET = async (req: NextRequest) => {
try {
const user = await getAuthenticatedUser();
if (!user) {
return Response.redirect(${env.NEXT_PUBLIC_BASE_URL}/login, 401);
}
return Response.redirect(env.NEXT_PUBLIC_BASE_URL, 201);
} catch (error) {
return Response.redirect(env.NEXT_PUBLIC_BASE_URL, 500);
}
};
Let me check the knowledge base for you again. Give me one moment! :books:
Your code is not correct for Next.js 14 App Router for several reasons:
-
Incorrect use of
Response.redirect:
The standardResponse.redirectfrom the Web API does not accept a status code as the second argument in the way you are using it. In Next.js App Router, you should useNextResponse.redirect(for middleware) or theredirectfunction fromnext/navigation(for Route Handlers and Server Components) redirect API reference. -
Redirects in Route Handlers:
In Route Handlers (e.g.,app/api/route.ts), you should use theredirectfunction fromnext/navigation, which throws and handles the redirect properly. You do not return aResponseobject for redirects. -
Status Codes:
Theredirectfunction does not allow you to set arbitrary status codes. It uses 307 (Temporary Redirect) by default, or 303 in Server Actions. If you need a permanent redirect (308), usepermanentRedirect.
Corrected Example:
import { redirect } from 'next/navigation'
import { env } from '@/env'
import { getAuthenticatedUser } from '../lib/utils'
export const GET = async (req: Request) => {
const user = await getAuthenticatedUser()
if (!user) {
redirect(`${env.NEXT_PUBLIC_BASE_URL}/login`)
}
redirect(env.NEXT_PUBLIC_BASE_URL)
}
- If you want to handle errors, you can use a try/catch, but remember that
redirectthrows, so it should be called outside thetryblock redirect API reference.
Summary:
- Use
redirectfromnext/navigationin App Router Route Handlers. - Do not use
Response.redirectwith a status code. - Do not return a
Responsefor redirects; just callredirect().
For more details, see the redirect function documentation.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow depot Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. Give me one moment! :books:
The error you are seeing (Error: NEXT_REDIRECT) is expected behavior when using the redirect function from next/navigation in Next.js App Router. The redirect function throws a special error (NEXT_REDIRECT) to signal to Next.js that a redirect should occur, and this error is not meant to be caught by your own try/catch blocks. If you catch it, you will see this error in your logs, and the redirect may not work as intended redirect API reference How to handle redirects in Next.js.
Key points from the documentation and issues:
- The
redirectfunction should be called outside oftry/catchblocks, because it throws an error to terminate the current rendering and perform the redirect. If you catch this error, it will not propagate as intended, and you will see theNEXT_REDIRECTerror in your logs redirect API reference How to handle redirects in Next.js. - This behavior is by design in Next.js 14 and 15, and is different from previous versions. The error is used internally to signal a redirect, and should not be handled by your own error handling logic Unexpected behaviour in redirect next/navigation function - Next.js 15 redirect() error from action caught in try/catch on client.
- If you need to handle other errors, you should structure your code so that
redirectis called outside thetry/catch, or filter out theNEXT_REDIRECTerror if you must use a catch block Unexpected behaviour in redirect next/navigation function - Next.js 15.
How to fix your code:
Move your redirect calls outside the try/catch block. For example:
import { redirect } from 'next/navigation';
export const GET = async () => {
const user = await getAuthenticatedUser();
if (!user || !user.helpdesk_password) {
redirect(env.NEXT_PUBLIC_BASE_URL);
}
// ... your logic
if (sidValue) {
// set cookie
}
redirect(`${env.HELPDESK_URL}/helpdesk/my-tickets`);
};
If you need to handle errors, only catch and handle non-redirect errors, or re-throw the redirect error using unstable_rethrow if you must catch all errors NEXT_REDIRECT internal error making it to the client.
Summary:
- Do not call
redirectinside atry/catchblock. - Let the
redirecterror propagate as intended by Next.js. - This is the documented and expected behavior in Next.js 14 App Router.
If you need more advanced error handling, see the redirect documentation and related GitHub issues for patterns on filtering or rethrowing internal errors.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@snow depot Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@haughty spire then rewrite it
Let me check the knowledge base for you again. Give me one moment! :books:
Certainly! Here’s how you should rewrite your handler for Next.js 14 App Router, based on the official documentation:
- Do not call
redirectinside atry/catchblock, asredirectthrows a special error that should not be caught by your code. - Instead, perform your checks and logic, and call
redirectoutside of anytry/catchblock. - If you need to handle errors, only catch and handle non-redirect errors, or use
unstable_rethrowif you must catch all errors (though this is advanced and not typically needed for most use cases).
Example (rewritten):
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { decryptHelpeskPassword } from '@/_lib/backend-helpers/authHelper';
import { env } from '@/env';
import { getAuthenticatedUser } from '../lib/utils';
export const GET = async () => {
const user = await getAuthenticatedUser();
if (!user || !user.helpdesk_password) {
redirect(env.NEXT_PUBLIC_BASE_URL);
}
let sidValue = null;
try {
const decryptedPassword = decryptHelpeskPassword(user.helpdesk_password);
const helpDeskRes = await fetch(`${env.HELPDESK_URL}/api/method/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `token ${process.env.NEXT_PUBLIC_HELPDESK_API_KEY}`,
},
body: JSON.stringify({
usr: user.email,
pwd: decryptedPassword,
}),
});
const setCookieHeader = helpDeskRes.headers.get('set-cookie');
if (setCookieHeader) {
const match = setCookieHeader.match(/sid=([^;]+)/);
if (match) {
sidValue = match[1];
}
}
} catch (error) {
console.error('Error in helpdesk route:', error);
redirect(env.NEXT_PUBLIC_BASE_URL);
}
if (sidValue) {
const cookie = cookies();
cookie.set('sid', sidValue, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7,
path: '/',
domain: .${new URL(env.HELPDESK_URL).hostname.split('.').slice(-2).join('.')},
});
}
redirect(${env.HELPDESK_URL}/helpdesk/my-tickets);
};
**Key points:**
- All `redirect` calls are outside the `try/catch` block, as required by Next.js 14 App Router [redirect API reference](<https://nextjs.org/docs/app/api-reference/functions/redirect>).
- This ensures the `NEXT_REDIRECT` error is not caught and the redirect works as intended.
If you need to handle errors more granularly, see the [unstable_rethrow documentation](<https://nextjs.org/docs/app/api-reference/functions/unstable_rethrow>), but for most cases, the above pattern is correct.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------