|
| 1 | +# URL Routing Strategy |
| 2 | + |
| 3 | +This document explains how URL routing works in the Cambridge Beer Festival app. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The app uses **path-based routing** (e.g., `/favorites`, `/drink/123`) instead of **hash-based routing** (e.g., `/#/favorites`, `/#/drink/123`). |
| 8 | + |
| 9 | +## Implementation |
| 10 | + |
| 11 | +### Flutter Side |
| 12 | + |
| 13 | +The app uses [go_router](https://pub.dev/packages/go_router) version 14.6.2 (or later) for routing. Starting from go_router 7.0.0, path-based URL strategy is the default on web platforms, so no additional configuration is needed in the Flutter code. |
| 14 | + |
| 15 | +### Web Server Configuration |
| 16 | + |
| 17 | +For path-based routing to work correctly on deployed web apps, the web server must be configured to serve `index.html` for all routes (SPA fallback). This is because when a user navigates directly to a route like `/favorites`, the web server needs to serve the main `index.html` file, which then loads the Flutter app that handles the routing internally. |
| 18 | + |
| 19 | +#### Cloudflare Pages (Production & Staging) |
| 20 | + |
| 21 | +**File**: `web/_redirects` |
| 22 | + |
| 23 | +``` |
| 24 | +/* /index.html 200 |
| 25 | +``` |
| 26 | + |
| 27 | +This tells Cloudflare Pages to serve `index.html` for all routes with a 200 status code. Cloudflare Pages natively supports the `_redirects` file format. |
| 28 | + |
| 29 | +#### Local Development with http-server |
| 30 | + |
| 31 | +For local testing, the project uses `http-server` with the `--proxy` flag to handle SPA routing: |
| 32 | + |
| 33 | +```bash |
| 34 | +npx http-server build/web -p 8080 -c-1 -a 127.0.0.1 --proxy http://127.0.0.1:8080? |
| 35 | +``` |
| 36 | + |
| 37 | +The `--proxy` flag tells http-server to fall back to serving `index.html` for routes that don't exist as physical files, enabling proper SPA behavior during local development and E2E testing. |
| 38 | + |
| 39 | +## Routes |
| 40 | + |
| 41 | +The app supports the following routes: |
| 42 | + |
| 43 | +- `/` - Home screen (drinks list) |
| 44 | +- `/favorites` - Favorites screen |
| 45 | +- `/about` - About screen |
| 46 | +- `/festival-info` - Festival information screen |
| 47 | +- `/drink/:id` - Drink detail screen (parameterized) |
| 48 | +- `/brewery/:id` - Brewery screen (parameterized) |
| 49 | +- `/style/:name` - Style screen (parameterized, URL-encoded) |
| 50 | + |
| 51 | +## Testing |
| 52 | + |
| 53 | +E2E tests in `test-e2e/routing.spec.ts` verify: |
| 54 | +- Path-based URLs work correctly |
| 55 | +- Deep linking to specific routes works |
| 56 | +- Browser back/forward buttons work |
| 57 | +- Page refresh preserves the current route |
| 58 | + |
| 59 | +## Benefits of Path-Based Routing |
| 60 | + |
| 61 | +1. **Better SEO**: Search engines can properly index individual pages |
| 62 | +2. **Clean URLs**: URLs look cleaner and more professional |
| 63 | +3. **Shareable Links**: Users can share direct links to specific content |
| 64 | +4. **Standard Web Behavior**: Works like traditional websites |
| 65 | +5. **Better Analytics**: Analytics tools can track page views more accurately |
| 66 | + |
| 67 | +## Migration Notes |
| 68 | + |
| 69 | +If you were previously using the app with hash-based routing, existing bookmarks with hash URLs (e.g., `/#/favorites`) will continue to work because go_router handles the migration automatically. |
0 commit comments