Skip to content

Commit ebac34b

Browse files
committed
fix(spa-fallback): always return index.html after refresh & 304 cache hit
* Strip 'If-None-Match' / 'If-Modified-Since' before proxying the request to index.html, forcing the asset-server to answer with 200 + body. * Treat 304 responses as success so the fallback still works when the file is cached. * Ensure Content-Type: text/html; charset=utf-8 is set to prevent MIME errors in the browser. * Leave static asset requests (.js, .css, images, etc.) untouched. This guarantees deep-link routes keep working after multiple page reloads and removes the 'Not Found / text/plain MIME type' error seen on the second refresh.
1 parent 9fdd02e commit ebac34b

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

webdev/lib/src/serve/webdev_server.dart

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,36 @@ class WebDevServer {
197197

198198
if (options.configuration.spaFallback) {
199199
FutureOr<Response> spaFallbackHandler(Request request) async {
200-
final uri = request.requestedUri;
201-
final hasExtension =
202-
uri.pathSegments.isNotEmpty && uri.pathSegments.last.contains('.');
203-
if (request.method != 'GET' || hasExtension) {
200+
final hasExt = request.url.pathSegments.isNotEmpty &&
201+
request.url.pathSegments.last.contains('.');
202+
if (request.method != 'GET' || hasExt) {
204203
return Response.notFound('Not Found');
205204
}
206-
final indexResponse =
207-
await assetHandler(request.change(path: 'index.html'));
208205

209-
return indexResponse.statusCode == 200
210-
? indexResponse
211-
: Response.notFound('Not Found');
206+
final indexUri =
207+
request.requestedUri.replace(path: 'index.html', query: '');
208+
209+
final cleanHeaders = Map.of(request.headers)
210+
..remove('if-none-match')
211+
..remove('if-modified-since');
212+
213+
final proxiedReq = Request(
214+
'GET',
215+
indexUri,
216+
headers: cleanHeaders,
217+
context: request.context,
218+
protocolVersion: request.protocolVersion,
219+
);
220+
221+
final resp = await assetHandler(proxiedReq);
222+
223+
if (resp.statusCode != 200 && resp.statusCode != 304) {
224+
return Response.notFound('Not Found');
225+
}
226+
return resp.change(headers: {
227+
...resp.headers,
228+
'content-type': 'text/html; charset=utf-8',
229+
});
212230
}
213231

214232
cascade = cascade.add(spaFallbackHandler);

0 commit comments

Comments
 (0)