next.config.js
Rama main · réplica de lectura del repositorio original.
const { withPlausibleProxy } = require('next-plausible')
const createNextIntlPlugin = require('next-intl/plugin')
const isDevelopment = process.env.NODE_ENV === 'development'
const plausibleSrc =
process.env.NEXT_PUBLIC_PLAUSIBLE_SRC || 'https://plausible.e30gallery.com/js/script.js'
const productionOrigins = ['https://e30gallery.com', 'https://cms.e30gallery.com']
const uniqueAllowedDomains = domains =>
[...new Set(domains.filter(domain => typeof domain === 'string' && domain.length > 0))]
const allowedDomains = uniqueAllowedDomains([
process.env.NEXT_PUBLIC_PAYLOAD_URL,
process.env.NEXT_PUBLIC_FRONTEND_URL,
process.env.NEXT_PUBLIC_SITE_URL,
...productionOrigins,
'https://art.kunstmatrix.com',
'https://www.artworkarchive.com',
'https://cdnjs.cloudflare.com',
'https://*.mailerlite.com',
'https://storage.mlcdn.com',
'https://groot.mailerlite.com',
'https://assets.mlcdn.com',
'https://connect.mailerlite.com',
'https://player.vimeo.com',
'https://www.youtube.com',
'https://plausible.e30gallery.com',
'https://challenges.cloudflare.com',
'https://*.cloudflare.com',
...(isDevelopment ? ['http://localhost:3000', 'http://localhost:5173'] : []),
])
const corsAllowOrigin = isDevelopment
? '*'
: process.env.NEXT_PUBLIC_FRONTEND_URL ||
process.env.NEXT_PUBLIC_SITE_URL ||
'https://e30gallery.com'
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline' ${allowedDomains.join(' ')};
style-src 'self' 'unsafe-inline' ${allowedDomains.join(' ')};
img-src 'self' data: blob: ${allowedDomains.join(' ')};
frame-src 'self' ${allowedDomains.join(' ')};
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self' ${allowedDomains.join(' ')};
frame-ancestors 'none';
connect-src 'self' ${isDevelopment ? '*' : allowedDomains.join(' ')};
${isDevelopment ? '' : 'upgrade-insecure-requests;'}
`
.replace(/\s{2,}/g, ' ')
.trim()
// Create the next-intl plugin
const withNextIntl = createNextIntlPlugin()
// Combine with the plausible proxy
const withPlugins = config => {
// First apply the base config to withPlausibleProxy
const withPlausible = withPlausibleProxy({
src: plausibleSrc,
})(config)
// Then apply withNextIntl to the result
return withNextIntl(withPlausible)
}
/** @type {import('next').NextConfig} */
const nextConfig = {
// Keep your existing settings
typescript: {
ignoreBuildErrors: false,
},
async headers() {
const securityHeaders = [
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
...(isDevelopment
? []
: [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
]),
]
return [
{
source: '/(.*)',
headers: [
...securityHeaders,
{
key: 'Access-Control-Allow-Credentials',
value: 'true',
},
{
key: 'Access-Control-Allow-Origin',
value: corsAllowOrigin,
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT',
},
{
key: 'Access-Control-Allow-Headers',
value:
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization, Origin, Cache-Control',
},
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
images: {
localPatterns: [
{
pathname: '/E30_logo.png',
search: '?v=1',
},
],
remotePatterns: [
{
protocol: 'https',
hostname: 'res.cloudinary.com',
port: '',
pathname: '/e30/image/upload/**',
},
{
protocol: 'https',
hostname: 'cms.e30gallery.com',
port: '',
pathname: '/**',
},
{
protocol: 'http',
hostname: 'localhost',
port: '3000',
pathname: '/**',
},
],
},
}
module.exports = withPlugins(nextConfig)