feat(typedserver): Add SPA fallback support to TypedServer
This commit is contained in:
@@ -56,6 +56,12 @@ export interface IServerOptions {
|
||||
feedMetadata?: plugins.smartfeed.IFeedOptions;
|
||||
articleGetterFunction?: () => Promise<plugins.tsclass.content.IArticle[]>;
|
||||
blockWaybackMachine?: boolean;
|
||||
|
||||
/**
|
||||
* SPA fallback - serve index.html for non-file routes (e.g., /login, /dashboard)
|
||||
* Useful for single-page applications with client-side routing
|
||||
*/
|
||||
spaFallback?: boolean;
|
||||
}
|
||||
|
||||
export type THttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'ALL';
|
||||
@@ -491,6 +497,41 @@ export class TypedServer {
|
||||
});
|
||||
}
|
||||
|
||||
// SPA fallback - serve index.html for non-file routes
|
||||
if (this.options.spaFallback && this.options.serveDir && method === 'GET' && !path.includes('.')) {
|
||||
try {
|
||||
const indexPath = plugins.path.join(this.options.serveDir, 'index.html');
|
||||
let html = await plugins.fsInstance.file(indexPath).encoding('utf8').read() as string;
|
||||
|
||||
// Inject reload script if enabled
|
||||
if (this.options.injectReload && html.includes('<head>')) {
|
||||
const injection = `<head>
|
||||
<!-- injected by @apiglobal/typedserver start -->
|
||||
<script async defer type="module" src="/typedserver/devtools"></script>
|
||||
<script>
|
||||
globalThis.typedserver = {
|
||||
lastReload: ${this.lastReload},
|
||||
versionInfo: ${JSON.stringify({}, null, 2)},
|
||||
}
|
||||
</script>
|
||||
<!-- injected by @apiglobal/typedserver stop -->
|
||||
`;
|
||||
html = html.replace('<head>', injection);
|
||||
}
|
||||
|
||||
return new Response(html, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'text/html; charset=utf-8',
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
appHash: this.serveHash,
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
// Fall through to 404
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return new Response('Not Found', { status: 404 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user