dotnet-serve
dotnet-serve copied to clipboard
Add FallbackToFile options for serving apps with client-side routing.
I have a react+typescript app use the React BrowserRouter.
For example, if I used React Router with a route for /todos , dotnet-serve will response a HTTP 404 .
This is because when there is a fresh page load for a /todos, the dotnet-server looks for the file build/todos{.html/htm} and does not find it. The dotnet-server should to be configured to respond to a request to /todos by serving index.html.
Describe the solution you'd like
Add options to configure FallbackToFile(...) endpoints. Such as :
dotnet serve --fallback-to-file "index.html"
I think this behavior already works. Can you send steps to reproduce the error you are seeing?
Here is what I did:
cd /tmp
mkdir issue104
cd issue104
mkdir todos
echo "<h2>hello</h2>" > todos/index.html
dotnet serve -o -p 5510
index.html is served when accessing

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost:5510/todos - -
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://localhost:5510/todos - - - 301 0 - 1.3907ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost:5510/todos/ - -
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/todos/index.html'. Physical path: '/private/tmp/issue104/todos/index.html'
Pre-requirements:
Produce steps:
npx create-react-app myapp
cd myapp
npm install -S react-router
npm add react-router-dom@6 history@5
Update index.js as following content:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
ReactDOM.render(
<Router>
<Routes>
<Route path="*" element={<App />}></Route>
</Routes>
</Router>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
The index configured path as '*' to render <App/> component.
Then build and serve:
yarn build
cd build
dotnet-serve
index.html is served when accessing 'http://localhost:54515' but not served when acessing 'http://localhost:54515/anypath'
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost:54515/anypath - -
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://localhost:54515/anypath - - - 404 - text/html 0.4621ms
index.html will match the browser url path to select component which should rendered.
dotnet-serve may serve './index.html' when accessing path '/any'.
Ok, I see what you are saying now. It sounds like you want all unknown routes to redirect to some default file. This behavior doesn't seem to me to be like a common use case. I don't plan to implement this, but I will leave this request open in case I am missing something.
Other users - please upvote if you want support for this feature request.
it's honestly the only reason I couldn't use it
this is a very common scenario for SPA apps, including blazor wasm
I don't develop features myself (project status https://github.com/natemcmaster/dotnet-serve/issues/43), but if this is something you would like to contribute, feel free to send a pull request.
Released in https://github.com/natemcmaster/dotnet-serve/releases/tag/v1.10.155