Steps to reproduce
Navigation via links work perfectly, but if you tried to access any page directly or refresh any page it will redirect you to home page.
What is expected ?
Access any page directly or refresh any page should not redirect to homepage
What is actually happening?
Access any page directly or refresh any page redirect you to home page.
Additional comments?
When the Content Security Policy (nuxt-security) is disabled, the problem is solved (I’m not sure), but this time settings such as css are corrupted.
Here is the website config nuxt.config.ts
typescript: {
includeWorkspace: true
},
experimental: {
asyncContext: true
},
app: {
head: {
meta: [
{ name: "viewport", content: "width=device-width, initial-scale=1, shrink-to-fit=no"},
{ name: "format-detection", content: "telephone=yes" },
{ name: "theme-color", content: "#ffffff " },
{ name: "msapplication-TileColor", content: "#da532c" },
{ property: "og:site:name", content: "Example" },
{ name: "og:type", property: "og:type", content: "website" },
{ property: "og:title", content: "Example" },
{ property: "og:url", content: process.env.BASE_URL },
{ property: "og:image", content: "/img/fl.webp" },
{ property: "og:image:secure_url", content: "/img/fl.webp" },
{ name: "twitter:url", content: process.env.BASE_URL },
{ name: "twitter:image", content: "/img/fl.webp" },
{ name: "twitter:image:alt", content: "Example" },
{ name: "twitter:card", content: "summary" },
{ name: "twitter:title", content: "Example" },
{ "http-equiv": "content-type", content: "text/html", charset: "utf-8" },
{ "http-equiv": "content-language", content: "tr" },
{ name: "robots", content: "index, follow" },
{ name: "revisit-after", content: "7 days" }
],
link: [
{ rel: "shortcut icon", type: "image/vnd.microsoft.icon", href: "/img/pwa/favicon.ico" },
{ rel: "canonical", href: process.env.BASE_URL },
{ rel: "apple-touch-icon", sizes: "180x180", href: "/img/pwa/apple-touch-icon.png" },
{ rel: "icon", type: "image/png", sizes: "16x16", href: "/img/pwa/favicon-16x16.png" },
{ rel: "icon", type: "image/png", sizes: "32x32", href: "/img/pwa/favicon-32x32.png" },
{ rel: "mask-icon", href: "/img/pwa/safari-pinned-tab.svg", color: "#5bbad5" },
{ rel: "preconnect", href: "https://www.google-analytics.com" }
],
script: [ { src: process.env.gtm, async: true }, { src: process.env.GOOGLE_RECAPTCHA, defer: true } ],
noscript: [{ children: "JavaScript is required." }]
}
},
modules: [
["@pinia/nuxt", {storesDirs: ["./store/**"]}],
"@vite-pwa/nuxt",
["nuxt-purgecss", { enabled: true, safelist: { deep: [/svg.*/, /fa.*/, /dark.*/, /light.*/] }, fontFace: true, variables: true, keyframes: true, rejected: true }],
"@nuxtjs/color-mode",
"nuxt-security",
"@nuxtjs/i18n",
["vue-recaptcha/nuxt", { enterprise: true }]
],
plugins: [ { src: "@/plugins/font-awesome.ts" }, { src: "@/plugins/useBootstrap.client.ts", mode: "client" }],
css: [
"@/assets/scss/app.scss",
"@fortawesome/fontawesome-svg-core/styles.css",
"/node_modules/flag-icons/css/flag-icons.min.css",
"/node_modules/bootstrap/dist/css/bootstrap.min.css"
],
router: {options: { linkActiveClass: "active" }},
routeRules: { "/": { prerender: true }, "/assets/**/*": { headers: { "cache-control": "public,max-age=31536000 ,s-maxage=31536000" }, cache: { maxAge: 31536000 } } },
postcss: {
plugins: {
cssnano: {
preset: "default"
}
}
},
build: {
transpile: ["@fortawesome/fontawesome-svg-core", "@fortawesome/free-brands-svg-icons", "@fortawesome/free-solid-svg-icons", "@fortawesome/free-regular-svg-icons", "@fortawesome/vue-fontawesome"],
analyze: { enabled: true }
},
nitro: {
compressPublicAssets: true,
minify: true,
publicAssets: [{ baseURL: "css", dir: "public/css", maxAge: 60 * 60 * 24 * 7 }, { dir: "public/img", maxAge: 60 * 60 * 24 * 7 }, { baseURL: "js", dir: "public/js", maxAge: 60 * 60 * 24 * 7 }, { baseURL: "video", dir: "public/video", maxAge: 60 * 60 * 24 * 30 }],
analyze: {
emitFile: true,
filename: "analysis.html",
title: "Analysis",
gzipSize: true,
brotliSize: true,
sourcemap: true
}
},
vite: {
css: { preprocessorOptions: { scss: { additionalData: "@use '@/assets/scss/globalVariables.scss' as *;" } } },
server: {
cors: {
methods: "GET, POST, DELETE",
origin: "*",
allowedHeaders: ["Content-Type", "Authorization"]
}
},
preview: { cors: { methods: ["GET", "POST", "DELETE"] } }
},
security: {
enabled: true,
corsHandler: {
origin: "*",
methods: ["GET", "POST", "DELETE"],
credentials: false
},
headers: {
xFrameOptions: "DENY",
xXSSProtection: "1; mod=block",
xPermittedCrossDomainPolicies: "none",
strictTransportSecurity: {
maxAge: 15552000,
includeSubdomains: true,
preload: true
},
contentSecurityPolicy: {
"base-uri": ["'none'"],
"default-src": ["'self'"],
"connect-src": ["'self'", "https://example.com"],
"font-src": ["'self'"],
"form-action": ["'self'"],
"frame-ancestors": ["'none'"],
"frame-src": ["'self'", "https://www.google.com"],
"img-src": ["'self'", "data:"],
"manifest-src": ["'self'"],
"media-src": ["'self'"],
"object-src": ["'none'"],
"script-src": ["'self'", 'https:', "'unsafe-inline'", "'strict-dynamic'", "'nonce-{{nonce}}'"],
"script-src-attr": ["'none'"],
"script-src-elem": ["'self'", "'unsafe-inline'", "https://www.google.com", "https://www.gstatic.com", "https://www.googletagmanager.com/gtag/js"],
"style-src": ["self", "'nonce-{{nonce}}'", "'strict-dynamic'", "https://example.com/"],
"style-src-attr": ["'self'", "'unsafe-inline'"],
"style-src-elem": ["'self'", "'unsafe-inline'"],
"worker-src": ["'self'"],
"upgrade-insecure-requests": true
},
originAgentCluster: "?1",
xContentTypeOptions: "nosniff",
referrerPolicy: "strict-origin-when-cross-origin",
xDownloadOptions: "noopen"
},
requestSizeLimiter: {
maxRequestSizeInBytes: 2000000,
maxUploadFileRequestInBytes: 8000000,
throwError: true
},
rateLimiter: {
tokensPerInterval: 150,
interval: "hour",
headers: true,
throwError: true
},
allowedMethodsRestricter: {
methods: ["GET", "POST", "DELETE"],
throwError: true
},
xssValidator: {
stripIgnoreTag: true,
stripIgnoreTagBody: true,
throwError: true,
css: true,
methods: ["GET", "POST", "DELETE"]
},
nonce: true,
sri: true,
ssr: true
},
pwa: {
useCredentials: true,
registerType: "autoUpdate",
includeAssets: ['apple-touch-icon.png', 'android-chrome-192x192.png', 'android-chrome-512x512.png', 'favicon.ico', 'favicon-16x16.png', 'favicon-32x32.png', 'mstile-150x150.png', 'safari-pinned-tab.svg'],
manifest: {
name: "Example",
short_name: "Example",
description: "Example",
theme_color: "#110F0F",
background_color: "#110F0F",
start_url: process.env.BASE_URL,
id: process.env.BASE_URL,
scope: process.env.BASE_URL,
orientation: "any",
icons: [
{
src: "/img/pwa/android-chrome-192x192.png",
type: "image/png",
sizes: "192x192"
},
{
src: "/img/pwa/android-chrome-512x512.png",
type: "image/png",
sizes: "512x512"
},
{
src: "/img/pwa/android-chrome-512x512.png",
type: "image/png",
sizes: "512x512",
purpose: "maskable"
}
],
display_override: ["fullscreen", "minimal-ui", "standalone"],
shortcuts: [
{
name: "Home Page",
url: "/",
description: "Home Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "Sectors",
url: "/sectors/list",
description: "Sectors Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "About",
url: "/about",
description: "About Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "Contact",
url: "/contact",
description: "Contact Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "Login",
url: "/login",
description: "Login Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "Register",
url: "/register",
description: "Register Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
},
{
name: "Profile",
url: "/profile",
description: "Profile Page",
icons: [
{
src: "/img/pwa/android-chrome-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any"
}
]
}
],
protocol_handlers: [
{ protocol: "mailto", url: `${process.env.BASE_URL}/newEmail?to=%s` }
]
},
workbox: {
globPatterns: ["**/*.{js,css,html,png,webp,ico,mp4,svg}"],
navigateFallback: "/",
offlineGoogleAnalytics: true,
clientsClaim: true,
cleanupOutdatedCaches: true
},
injectManifest: {
globPatterns: ["**/*.{js,css,html,png,webp,ico,mp4,svg}"]
}
},
i18n: {
baseUrl: process.env.BASE_URL,
experimental: { autoImportTranslationFunctions: true },
langDir: "locales/",
strategy: "no_prefix",
skipSettingLocaleOnNavigate: true,
defaultLocale: "tr",
detectBrowserLanguage: {
useCookie: true,
fallbackLocale: "tr",
alwaysRedirect: true,
cookieSecure: true,
redirectOn: "root",
cookieKey: "lng"
},
locales: [
{ code: "tr", iso: "tr-TR", name: "Türkçe", file: "tr.json", flag: "fi fi-tr" },
{ code: "en", iso: "en-US", name: "English", file: "en.json", flag: "fi fi-gb" }
]
}