Skip to content

Commit 96201aa

Browse files
committed
docs: add frontend routing documentation and setup guide
1 parent f1a8486 commit 96201aa

File tree

2 files changed

+269
-0
lines changed

2 files changed

+269
-0
lines changed

README-adding-routes.md

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# Adding a New Route/Page/Component
2+
3+
This guide explains how to add a new route, page, or component to the application using our router setup.
4+
5+
## Overview
6+
7+
Our application uses a Single Page Application (SPA) router with helper utilities that simplify adding and managing routes. The router handles page transitions, authentication checks, and subscription requirements with minimal code.
8+
9+
## Step-by-Step Guide
10+
11+
### 1. Create the HTML View File
12+
13+
First, create an HTML file for your new page in the `/views` directory:
14+
15+
```html
16+
<!-- /views/my-new-feature.html -->
17+
<!DOCTYPE html>
18+
<html lang="en">
19+
<head>
20+
<meta charset="UTF-8">
21+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
22+
<title>My New Feature</title>
23+
<link rel="stylesheet" href="/css/main.css">
24+
</head>
25+
<body>
26+
<div class="my-feature-container">
27+
<h1 data-i18n="my_feature.title">My New Feature</h1>
28+
<p data-i18n="my_feature.description">This is my new feature page.</p>
29+
30+
<!-- Your page content here -->
31+
<div class="feature-content">
32+
<form id="my-feature-form">
33+
<!-- Form fields -->
34+
<button type="submit" data-i18n="my_feature.submit">Submit</button>
35+
</form>
36+
</div>
37+
</div>
38+
</body>
39+
</html>
40+
```
41+
42+
### 2. Create an Initializer Function (Optional)
43+
44+
If your page needs JavaScript initialization (event listeners, data loading, etc.), create an initializer function in `page-initializers.js`:
45+
46+
```javascript
47+
/**
48+
* Initialize the new feature page
49+
*/
50+
export function initMyNewFeaturePage() {
51+
console.log('Initializing my new feature page');
52+
53+
// Get elements
54+
const form = document.getElementById('my-feature-form');
55+
if (!form) {
56+
console.error('My feature form not found');
57+
return;
58+
}
59+
60+
// Add event listeners
61+
form.addEventListener('submit', async (e) => {
62+
e.preventDefault();
63+
64+
// Form submission logic
65+
console.log('Form submitted');
66+
67+
// Get form data
68+
const formData = new FormData(form);
69+
const formDataObj = Object.fromEntries(formData.entries());
70+
71+
// Process the form data
72+
console.log('Form data:', formDataObj);
73+
74+
// Additional logic...
75+
});
76+
77+
// Other initialization code...
78+
}
79+
```
80+
81+
Don't forget to export the initializer function at the top of the file:
82+
83+
```javascript
84+
export {
85+
// ... existing exports
86+
initMyNewFeaturePage
87+
} from './page-initializers.js';
88+
```
89+
90+
### 3. Add the Route to the Router
91+
92+
#### Approach 1: Add Directly to router.js
93+
94+
Open `router.js` and add your new route to the `createRoutes` call in the `defineRoutes` function:
95+
96+
```javascript
97+
// In router.js
98+
export function defineRoutes(router) {
99+
console.log('Defining routes...');
100+
101+
// Define routes using the createRoutes helper
102+
const routes = createRoutes({
103+
// Existing routes...
104+
'/': '/views/home.html',
105+
106+
// Add your new route
107+
'/my-new-feature': {
108+
viewPath: '/views/my-new-feature.html',
109+
afterRender: initMyNewFeaturePage, // Optional
110+
requireAuth: true // If the route requires authentication
111+
}
112+
});
113+
114+
// Rest of the function...
115+
}
116+
```
117+
118+
#### Approach 2: Create a Separate Routes File
119+
120+
For better organization in larger applications, you can create a separate file for related routes:
121+
122+
```javascript
123+
// feature-routes.js
124+
import { createRoutes } from './route-helpers.js';
125+
import { initMyNewFeaturePage } from './page-initializers.js';
126+
127+
export const featureRoutes = createRoutes({
128+
'/my-new-feature': {
129+
viewPath: '/views/my-new-feature.html',
130+
afterRender: initMyNewFeaturePage,
131+
requireAuth: true
132+
},
133+
'/my-new-feature/settings': {
134+
viewPath: '/views/my-new-feature-settings.html',
135+
requireAuth: true
136+
}
137+
});
138+
```
139+
140+
Then import and merge these routes in `router.js`:
141+
142+
```javascript
143+
// In router.js
144+
import { featureRoutes } from './feature-routes.js';
145+
146+
export function defineRoutes(router) {
147+
console.log('Defining routes...');
148+
149+
// Define core routes
150+
const coreRoutes = createRoutes({
151+
// Existing routes...
152+
});
153+
154+
// Merge all routes
155+
const routes = {
156+
...coreRoutes,
157+
...featureRoutes
158+
// Add more route collections as needed
159+
};
160+
161+
// Register routes with the router
162+
router.registerRoutes(routes);
163+
164+
// Rest of the function...
165+
}
166+
```
167+
168+
## Route Configuration Options
169+
170+
When adding a route, you can use these options:
171+
172+
| Option | Type | Description |
173+
|--------|------|-------------|
174+
| `viewPath` | String | Path to the HTML view file |
175+
| `afterRender` | Function | Function to run after the page is rendered |
176+
| `beforeEnter` | Function | Function to run before entering the route |
177+
| `requireAuth` | Boolean | Whether the route requires authentication |
178+
| `requireSubscription` | Boolean | Whether the route requires an active subscription |
179+
180+
## Examples
181+
182+
### Basic Route
183+
184+
```javascript
185+
'/about': '/views/about.html'
186+
```
187+
188+
### Route with Initialization
189+
190+
```javascript
191+
'/profile': {
192+
viewPath: '/views/profile.html',
193+
afterRender: initProfilePage
194+
}
195+
```
196+
197+
### Protected Route (Requires Authentication)
198+
199+
```javascript
200+
'/dashboard': {
201+
viewPath: '/views/dashboard.html',
202+
requireAuth: true
203+
}
204+
```
205+
206+
### Premium Route (Requires Subscription)
207+
208+
```javascript
209+
'/premium-feature': {
210+
viewPath: '/views/premium-feature.html',
211+
requireSubscription: true
212+
}
213+
```
214+
215+
### Route with Custom Guard
216+
217+
```javascript
218+
'/admin': {
219+
viewPath: '/views/admin.html',
220+
beforeEnter: (to, from, next) => {
221+
const userRole = localStorage.getItem('user_role');
222+
if (userRole === 'admin') {
223+
next();
224+
} else {
225+
next('/access-denied');
226+
}
227+
}
228+
}
229+
```
230+
231+
## Testing Your New Route
232+
233+
After adding the route, you can test it by navigating to the URL in your browser:
234+
235+
```
236+
http://localhost:3000/my-new-feature
237+
```
238+
239+
The router will handle loading the HTML, running the initializer function, and checking authentication if required.
240+
241+
## Best Practices
242+
243+
1. **Organize Related Routes**: Keep related routes together, either in the same section of `router.js` or in a separate routes file.
244+
245+
2. **Use Descriptive Route Names**: Choose route paths that clearly describe the feature or page.
246+
247+
3. **Follow Naming Conventions**: Use consistent naming for HTML files, initializer functions, and route paths.
248+
249+
4. **Handle Authentication Properly**: Use the `requireAuth` option for protected routes instead of implementing custom checks.
250+
251+
5. **Add Internationalization**: Use `data-i18n` attributes for text that needs to be translated.
252+
253+
6. **Clean Up Event Listeners**: If your initializer adds event listeners, make sure to remove them when the page is unloaded to prevent memory leaks.
254+
255+
7. **Test Thoroughly**: Test your new route with different scenarios (logged in, logged out, with/without subscription) to ensure it behaves correctly.

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,18 @@ node scripts/test-pdf-generation.js
402402

403403
This script will generate a test PDF and output the detected Chrome path.
404404

405+
## Frontend Development
406+
407+
This application uses a custom SPA (Single Page Application) router for frontend navigation. The router handles page transitions, authentication checks, and subscription requirements.
408+
409+
### Adding New Routes
410+
411+
For detailed instructions on how to add new routes, pages, or components to the application, see the [Adding Routes Guide](README-adding-routes.md).
412+
413+
This guide covers:
414+
- Creating HTML view files
415+
- Setting up page initializers
416+
- Adding routes to the router
417+
- Handling authentication and subscription requirements
418+
- Best practices for route management
405419

0 commit comments

Comments
 (0)