Extending the web
The web is grouped by features.
Codebase structure
The web has a feature-based folder structure.
├── web/
│ └── src/
│ ├── api/
│ ├── common/
│ ├── features/
│ │ ├── todos/
│ │ └── ...
│ ├── hooks/
│ └── pages/
└── ...
api
contains the auto-generated API clientcommon
contains shared code like generic componentsfeatures
contains features e.g. todo-listhooks
contains re-usable hookspages
contains entrypoints (pages that are used by the router)
Application tree
flowchart
subgraph web
AuthProvider-. imported from .->react-oauth2-code-pkce;
index --> AuthProvider
AuthProvider --> app
app --> Header
app --> RouterProvider
RouterProvider-. imported from .->react-router-dom;
RouterProvider --> routes
routes -- /invalid --> InvalidUrl
routes -- / --> TodoListPage
TodoListPage --> TodoList
TodoList -- uses hook --> useTodos
useTodos -- uses client --> TodoAPI
TodoList --> AddItem
TodoList -- 1..x --> TodoItem
end
TodoAPI -- HTTP requests --> API
style react-oauth2-code-pkce fill:#f96;
click react-oauth2-code-pkce "https://www.npmjs.com/package/react-oauth2-code-pkce" "Open"
style react-router-dom fill:#f96;
click react-router-dom "https://www.npmjs.com/package/react-router-dom" "Open"
style useTodos fill:#b8c;
External dependencies:
- The app is using react-oauth2-code-pkce for Oauth2 authentication.
- The app is using react-router-dom for routing.
Configuration
See configuration for a description of the different configuration options available.
Oauth2
The AuthProvider are using the configuration defined in web/src/auth
.
import type { TAuthConfig } from 'react-oauth2-code-pkce'
export const authConfig: TAuthConfig = {
clientId: import.meta.env.VITE_AUTH_CLIENT_ID || '',
authorizationEndpoint: import.meta.env.VITE_AUTH_ENDPOINT || '',
tokenEndpoint: import.meta.env.VITE_TOKEN_ENDPOINT || '',
scope: import.meta.env.VITE_AUTH_SCOPE || '',
redirectUri: import.meta.env.VITE_AUTH_REDIRECT_URI || '',
logoutEndpoint: import.meta.env.VITE_LOGOUT_ENDPOINT || '',
autoLogin: false,
preLogin: () =>
localStorage.setItem(
'preLoginPath',
`${window.location.pathname}${window.location.search}${window.location.hash}`
),
postLogin: () =>
window.location.replace(localStorage.getItem('preLoginPath') ?? (import.meta.env.VITE_AUTH_REDIRECT_URI || '')),
}
Routes
The RouterProvider are using the router defined in web/src/router
.
import { createBrowserRouter } from 'react-router-dom'
import InvalidUrl from './common/components/InvalidUrl'
import { TodoListPage } from './pages/TodoListPage'
export const router = createBrowserRouter([
{
path: '/',
element: <TodoListPage />,
},
{
path: '*',
element: <InvalidUrl />,
},
])