Skip to content

Commit 577f150

Browse files
committed
Fixed admin deep links with yarn dev:forward
closes https://linear.app/ghost/issue/BER-3090/invites-are-broken-in-yarn-devforward We need to handle deep links the same way as the Ghost backend in the Vite dev server for invite links and password resets to work as expected.
1 parent 362bda8 commit 577f150

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

apps/admin/tsconfig.node.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
"noFallthroughCasesInSwitch": true,
2222
"noUncheckedSideEffectImports": true
2323
},
24-
"include": ["vite.config.ts", "vite-ember-assets.ts", "vite-backend-proxy.ts"]
24+
"include": ["./vite*.ts",]
2525
}

apps/admin/vite-deep-links.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Plugin, ViteDevServer, PreviewServer } from "vite";
2+
3+
/**
4+
* Vite plugin that redirects admin deep-link URLs to hash-based URLs.
5+
*
6+
* Mirrors ghost/core/core/server/web/admin/middleware/redirect-admin-urls.js
7+
* so that direct navigation to paths like /ghost/posts/123 redirects to /ghost/#/posts/123
8+
*
9+
* By registering as a post-middleware, static assets and API requests are handled first,
10+
* and only unhandled requests trigger the redirect.
11+
*/
12+
export function deepLinksPlugin(): Plugin {
13+
function addRedirectMiddleware(server: ViteDevServer | PreviewServer) {
14+
const base = (server.config.base ?? "/ghost").replace(/\/$/, "");
15+
const pathRegex = new RegExp(`^${base}/(.+)`);
16+
17+
return () => {
18+
server.middlewares.use((req, res, next) => {
19+
const match = req.originalUrl?.match(pathRegex);
20+
21+
if (match) {
22+
res.writeHead(302, { Location: `${base}/#/${match[1]}` });
23+
res.end();
24+
return;
25+
}
26+
27+
next();
28+
});
29+
};
30+
}
31+
32+
return {
33+
name: "deep-links",
34+
configureServer: addRedirectMiddleware,
35+
configurePreviewServer: addRedirectMiddleware,
36+
};
37+
}

apps/admin/vite.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import react from "@vitejs/plugin-react-swc";
55

66
import { emberAssetsPlugin } from "./vite-ember-assets";
77
import { ghostBackendProxyPlugin } from "./vite-backend-proxy";
8+
import { deepLinksPlugin } from "./vite-deep-links";
89

910
const GHOST_CARDS_PATH = resolve(__dirname, "../../ghost/core/core/frontend/src/cards");
1011

1112
// https://vite.dev/config/
1213
export default defineConfig({
1314
base: process.env.GHOST_CDN_URL ?? "/ghost",
14-
plugins: [react(), emberAssetsPlugin(), ghostBackendProxyPlugin(), tsconfigPaths()],
15+
plugins: [react(), emberAssetsPlugin(), ghostBackendProxyPlugin(), deepLinksPlugin(), tsconfigPaths()],
1516
define: {
1617
"process.env.DEBUG": false, // Shim env var utilized by the @tryghost/nql package
1718
},

0 commit comments

Comments
 (0)