Browse Source

📝 Add docs for Frontend

pull/15800/head
Sebastián Ramírez 1 month ago
parent
commit
dc6db7ffe3
  1. 119
      docs/en/docs/tutorial/frontend.md
  2. 8
      docs/en/docs/tutorial/static-files.md
  3. 1
      docs/en/mkdocs.yml

119
docs/en/docs/tutorial/frontend.md

@ -0,0 +1,119 @@
# Frontend { #frontend }
You can serve static frontend apps with `app.frontend()` (or `router.frontend()`).
This is useful for frontend tools that generate static files, like React with Vite, TanStack Router, Astro, Vue, Svelte, Angular, Solid, and others.
With these tools, you normally have a step that builds the frontend, with a command like:
```bash
npm run build
```
That would generate a directory like `./dist/` with your frontend files.
You can use `app.frontend()` to serve that directory following the conventions needed by these frontend frameworks.
**FastAPI** checks *path operations* first. The frontend files are checked only if no normal route matched, so your API won't be affected.
## Serve a Frontend { #serve-a-frontend }
After building your frontend, for example with `npm run build`, put the generated files in a directory, for example, `dist`.
Your project structure could look like this:
```text
.
├── pyproject.toml
├── app
│ ├── __init__.py
│ └── main.py
└── dist
├── index.html
└── assets
└── app.js
```
Then serve it with `app.frontend()`:
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
With this, a request for `/assets/app.js` can serve `dist/assets/app.js`.
If you also have a **FastAPI** *path operation*, the *path operation* wins.
## Client-Side Routing { #client-side-routing }
Many frontend apps, including **single-page apps** (SPAs), use client-side routing. A path like `/dashboard/settings` might not be a real file but the framework would take care of handling it.
So, if accessing that URL directly (instead of navigating through the app), the backend should serve the frontend app from `index.html`, so that the frontend framework can then handle the client-side routing.
For that, use `fallback="index.html"`:
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
**FastAPI** uses this fallback only for requests that look like browser navigation. Missing files like JavaScript, CSS, and images still return `404`.
/// tip
By default, `fallback` has a value of `fallback="auto"`. In most cases you won't need to specify `fallback`. Read below for details.
///
This is what you would want with many frontend apps that use client-side routing, for example, React with TanStack Router, Vue, Angular, SvelteKit, or Solid.
## Custom 404 Page { #custom-404-page }
You can also serve a static `404.html` page for missing frontend paths:
{* ../../docs_src/frontend/tutorial003_py310.py hl[5] *}
That response keeps a status code of `404`.
In this case, **FastAPI** won't serve `index.html` for missing frontend paths. It will return the `404.html` file instead.
/// tip
By default, `fallback` has a value of `fallback="auto"`. With this, if a `404.html` file is found, it will be used as the fallback automatically.
So, you can normally omit the `fallback` argument.
///
This is useful with frontend tools that generate static HTML files for each page, like Astro.
## Fallback Auto { #fallback-auto }
By default, `app.frontend()` uses `fallback="auto"`.
If there is a `404.html` file in the frontend directory, missing frontend paths serve that file with status code `404`.
Otherwise, if there is an `index.html` file, missing browser navigation paths serve `index.html`, which is what many frontend apps with client-side routing expect.
So, in most cases you can use `app.frontend("/", directory="dist")` without specifying the `fallback` argument.
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
## Disable Fallback { #disable-fallback }
If you don't want to serve a fallback file for missing frontend paths, use `fallback=None`:
{* ../../docs_src/frontend/tutorial005_py310.py hl[5] *}
Then missing frontend paths return the normal `404`.
## Use it with `APIRouter` { #use-it-with-apirouter }
You can also add frontend files to an `APIRouter` and include it with a prefix:
{* ../../docs_src/frontend/tutorial004_py310.py hl[6,7] *}
In this example, frontend paths are served under `/app`.
Any regular *path operations* in the app will still take precedence, including in other routers.
## Static Build Output Only { #static-build-output-only }
`app.frontend()` serves files already generated by your frontend build.
It does not run server-side rendering. It is for frontend frameworks that generate static files, not for frameworks that need dynamic rendering on the server for each request.

8
docs/en/docs/tutorial/static-files.md

@ -2,6 +2,14 @@
You can serve static files automatically from a directory using `StaticFiles`.
/// tip
If you need to host a frontend, use `app.frontend()` instead, read about it in [Frontend](frontend.md).
`app.frontend()` uses `StaticFiles` underneath, with several additional advantages for frontends, like handling client-side routing.
///
## Use `StaticFiles` { #use-staticfiles }
* Import `StaticFiles`.

1
docs/en/mkdocs.yml

@ -133,6 +133,7 @@ nav:
- tutorial/server-sent-events.md
- tutorial/background-tasks.md
- tutorial/metadata.md
- tutorial/frontend.md
- tutorial/static-files.md
- tutorial/testing.md
- tutorial/debugging.md

Loading…
Cancel
Save