Replies: 6 comments 9 replies
-
Facing the same issue. |
Beta Was this translation helpful? Give feedback.
-
As mentioned above, we're having trouble adding the export default async function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'nonce-${nonce}';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
block-all-mixed-content;
upgrade-insecure-requests;
`
// Replace newline characters and spaces
const contentSecurityPolicyHeaderValue = cspHeader
.replace(/\s{2,}/g, ' ')
.trim()
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-nonce', nonce)
requestHeaders.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
// Step 1: Use the incoming request (example)
const defaultLocale = request.headers.get('x-default-locale') || 'en';
// Step 2: Create and call the next-intl middleware (example)
const handleI18nRouting = createIntlMiddleware({
locales: ['en', 'de'],
defaultLocale,
localePrefix: "as-needed",
});
const response = handleI18nRouting(request);
// How can we add the `requestHeaders` with createIntlMiddleware ?
/*
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
})
*/
// Step 3: Alter the response (example)
response.headers.set('x-default-locale', defaultLocale);
response.headers.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
return response;
}
export const config = {
matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
}; |
Beta Was this translation helpful? Give feedback.
-
I am having the same problem.. trying to solve for days... |
Beta Was this translation helpful? Give feedback.
-
The following is a working example of using next-intl with NextAuth and adding a // Compile a list of all locales
const allLocales = locales.concat(betaLocales)
const publicPages = ["/auth/login", "/auth/error", "/events/.*"]
// Configure next-intl middleware
const intlMiddleware = createIntlMiddleware({
locales: allLocales,
defaultLocale: "en-US",
localePrefix: "always",
})
const authMiddleware = withAuth(
function onSuccess(req) {
const response = intlMiddleware(req)
const csp = req.headers.get("Content-Security-Policy")
if (!csp) {
throw new Error("No CSP header found")
}
response.headers.set("Content-Security-Policy", csp)
return response
},
{
callbacks: {
authorized: ({ token }) => token !== null,
},
pages: {
signIn: "/auth/login",
signOut: "/",
error: "/auth/error",
},
},
)
export default function middleware(request: NextRequest) {
const publicPathnameRegex = RegExp(
`^(/(${locales.join("|")}))?(${publicPages.join("|")})/?$`,
"i",
)
const isPublicPage = publicPathnameRegex.test(request.nextUrl.pathname)
const nonce = Buffer.from(crypto.randomUUID()).toString("base64")
const cspWithNonce = csp(nonce) // Generate the CSP as described in the Next docs
const requestHeaders = new Headers(request.headers)
requestHeaders.set("x-nonce", nonce)
requestHeaders.set("Content-Security-Policy", cspWithNonce)
const req = new NextRequest(request, {
headers: requestHeaders,
})
// Handle the request with the appropriate middleware
let response: NextResponse
if (isPublicPage) {
response = intlMiddleware(req)
response.headers.set("Content-Security-Policy", cspWithNonce)
} else {
response = (authMiddleware as unknown as typeof intlMiddleware)(req)
}
return response
}
export const config = {
matcher: [
"/((?!_next/static|.well-known|fonts|icons|images|favicon.ico|apple-touch-icon.png|service-worker.js|version).*)",
],
} |
Beta Was this translation helpful? Give feedback.
-
I'm facing the same issue, please try this approach import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
import createIntlMiddleware from 'next-intl/middleware';
// Configuration for next-intl middleware
const intlMiddleware = createIntlMiddleware({
locales: ['en', 'ko'], // Add your supported locales
defaultLocale: 'en',
});
export async function middleware(request: NextRequest, event: NextFetchEvent) {
// Run next-intl middleware
const intlResponse = intlMiddleware(request);
// Generate nonce and set CSP headers
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
console.log('Generated Nonce:', nonce);
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`;
const contentSecurityPolicyHeaderValue = cspHeader.replace(/\s{2,}/g, ' ').trim();
// Merge headers from both responses
const response = intlResponse || NextResponse.next();
response.headers.set('x-nonce', nonce);
response.headers.set('Content-Security-Policy', contentSecurityPolicyHeaderValue);
return response;
}
export const config = {
matcher: [
// Enable a redirect to a matching locale at the root
'/',
// Set a cookie to remember the previous locale for
// all requests that have a locale prefix
'/(en|ko)/:path*',
// Enable redirects that add missing locales
// (e.g. `/pathnames` -> `/en/pathnames`)
'/((?!api|_next|_vercel|.*\\..*).*)',
],
}; |
Beta Was this translation helpful? Give feedback.
-
There is a problem with the approach I posted above in that I think you can do this instead:
Edit: This is correct in @realrisman approach above |
Beta Was this translation helpful? Give feedback.
-
We'd like to implement Content Security Policy, but we're having trouble working out how to integrate it using Next-intl's custom middleware. Has anyone already done this?
Here's the Next documentation to add CSP:
Here's the next-intl middleware:
Beta Was this translation helpful? Give feedback.
All reactions