diff --git a/frontend/src/entries/api-docs.tsx b/frontend/src/entries/api-docs.tsx index 9a32c5cd..f84b7e95 100644 --- a/frontend/src/entries/api-docs.tsx +++ b/frontend/src/entries/api-docs.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/clients.tsx b/frontend/src/entries/clients.tsx index a6834e3f..ff654119 100644 --- a/frontend/src/entries/clients.tsx +++ b/frontend/src/entries/clients.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/inbounds.tsx b/frontend/src/entries/inbounds.tsx index f59a16e9..841b643d 100644 --- a/frontend/src/entries/inbounds.tsx +++ b/frontend/src/entries/inbounds.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/index.tsx b/frontend/src/entries/index.tsx index c3620cae..e57f3be3 100644 --- a/frontend/src/entries/index.tsx +++ b/frontend/src/entries/index.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/login.tsx b/frontend/src/entries/login.tsx index 66fc4f1a..75c933fe 100644 --- a/frontend/src/entries/login.tsx +++ b/frontend/src/entries/login.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/nodes.tsx b/frontend/src/entries/nodes.tsx index 75761eba..c639ef34 100644 --- a/frontend/src/entries/nodes.tsx +++ b/frontend/src/entries/nodes.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/settings.tsx b/frontend/src/entries/settings.tsx index b6397963..0ee78267 100644 --- a/frontend/src/entries/settings.tsx +++ b/frontend/src/entries/settings.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/entries/subpage.tsx b/frontend/src/entries/subpage.tsx index fbe6ea75..b4dbaab7 100644 --- a/frontend/src/entries/subpage.tsx +++ b/frontend/src/entries/subpage.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { readyI18n } from '@/i18n/react'; import { ThemeProvider } from '@/hooks/useTheme'; import SubPage from '@/pages/sub/SubPage'; diff --git a/frontend/src/entries/xray.tsx b/frontend/src/entries/xray.tsx index 3b579254..c9f92f17 100644 --- a/frontend/src/entries/xray.tsx +++ b/frontend/src/entries/xray.tsx @@ -2,6 +2,7 @@ import { createRoot } from 'react-dom/client'; import { message } from 'antd'; import 'antd/dist/reset.css'; +import '@/utils/chunkReload'; import { setupAxios } from '@/api/axios-init.js'; import { applyDocumentTitle } from '@/utils'; import { readyI18n } from '@/i18n/react'; diff --git a/frontend/src/utils/chunkReload.ts b/frontend/src/utils/chunkReload.ts new file mode 100644 index 00000000..1f6d6fc0 --- /dev/null +++ b/frontend/src/utils/chunkReload.ts @@ -0,0 +1,17 @@ +// After a panel upgrade the embedded dist/ ships with new hashed chunk +// filenames, so an SPA that was loaded before the upgrade still holds +// references to chunks that no longer exist on the server. The first +// time a lazy import 404s we force a full reload so the browser picks +// up the new index.html and its new chunk references. +if (typeof window !== 'undefined') { + const RELOAD_FLAG = '__xuiChunkReloadOnce'; + window.addEventListener('vite:preloadError', (event) => { + event.preventDefault(); + if (sessionStorage.getItem(RELOAD_FLAG) === '1') return; + sessionStorage.setItem(RELOAD_FLAG, '1'); + window.location.reload(); + }); + window.addEventListener('load', () => { + sessionStorage.removeItem(RELOAD_FLAG); + }); +}