Skip to main content

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 client
  • common contains shared code like generic components
  • features contains features e.g. todo-list
  • hooks contains re-usable hooks
  • pages 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:

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 />,
},
])