I have the following problem after deploying a new version to my vue 3 application. The problem is that every site the user has visited in his current session is still cached in his browser even though i already have set all no-store, no-caching, etc. header and i can confirm via browser that all files have that header set. I already give an hash value to all new files during build and remove the old files. I guess cause i dynamically import the files via vue router they get cached automatically and i cant find a way to stop that. I even tried to append a date to the import statements with a timestamp but it seems like that is just run once and thats it. Im getting kinda clueless and dont know what another way could be. I dont want to tell my users to manually refresh after deployment every time. What could i do?
Setup: Using Vite + Vue 3 + vue-router Deployment on IIS Server + Newest Edge Browser (Chrome based)
vite.config.ts
const hash = Math.floor(Math.random() * 90000) + 10000;
..
build: {
rollupOptions: {
output: {
entryFileNames: `[name]` + hash + `.js`,
chunkFileNames: `[name]` + hash + `.js`,
assetFileNames: `[name]` + hash + `.[ext]`
}
},
headers: {
// Cache-Control für alle statischen Ressourcen setzen
'Cache-Control': 'max-age=0, no-store, no-cache, must-revalidate, proxy-revalidate'
}
}
web.config (on IIS)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<!-- URL-Rewriting für Vue.js History Mode -->
<rewrite>
<rules>
<rule name="VueHistoryMode" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<!-- Optional: Ausschluss von spezifischen API-Pfaden von der Rewrite-Regel -->
<!-- <add input="{REQUEST_URI}" pattern="^/api" negate="true" /> -->
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
<!-- HTTP-Header für das Verhindern von Caching -->
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-store, no-cache, must-revalidate, proxy-revalidate" />
<add name="Pragma" value="no-cache" />
<add name="Expires" value="0" />
</customHeaders>
</httpProtocol>
<!-- Statische Inhalte und deren Cache-Einstellungen -->
<staticContent>
<clientCache cacheControlMode="DisableCache" />
<remove fileExtension=".svg" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<remove fileExtension=".webp" />
<mimeMap fileExtension=".webp" mimeType="image/webp" />
</staticContent>
</system.webServer>
</configuration>
Router.ts
// This is how i import the components
component: () => import('@/home/Home.vue'),
// This is working like i want it to be but not on sites the user has already loaded in that tab before deployment
router.onError((error, to) => {
if (error.message.includes('Failed to fetch dynamically imported module')
|| error.message.includes('Importing a module script failed')) {
console.log(to?.fullPath);
if (!to?.fullPath) {
window.location.reload();
} else {
window.location.href = to.fullPath;
}
}
});
I need an easy way to automatically update the site for my users, best case as soon as they change the site they are currently working in. I dont want to tell my users to manually reload the site. After reloading all is fine, cause then the newest site is shown.
What i have tried:
- add hash to vite.config.ts
- add cache control headers to vite config + iis config
- add common http response headers and set expire web content -> immediately
Duxhamm is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.