← full-stack-fastapi-template  /  frontend/src/main.tsx

1
import {
2
  MutationCache,
3
  QueryCache,
4
  QueryClient,
5
  QueryClientProvider,
6
} from "@tanstack/react-query"
7
import { createRouter, RouterProvider } from "@tanstack/react-router"
8
import { StrictMode } from "react"
9
import ReactDOM from "react-dom/client"
10
import { ApiError, OpenAPI } from "./client"
11
import { ThemeProvider } from "./components/theme-provider"
12
import { Toaster } from "./components/ui/sonner"
13
import "./index.css"
14
import { routeTree } from "./routeTree.gen"
15
16
OpenAPI.BASE = import.meta.env.VITE_API_URL
17
OpenAPI.TOKEN = async () => {
18
  return localStorage.getItem("access_token") || ""
19
}
20
21
const handleApiError = (error: Error) => {
22
  if (error instanceof ApiError && [401, 403].includes(error.status)) {
23
    localStorage.removeItem("access_token")
24
    window.location.href = "/login"
25
  }
26
}
27
const queryClient = new QueryClient({
28
  queryCache: new QueryCache({
29
    onError: handleApiError,
30
  }),
31
  mutationCache: new MutationCache({
32
    onError: handleApiError,
33
  }),
34
})
35
36
const router = createRouter({ routeTree })
37
declare module "@tanstack/react-router" {
38
  interface Register {
39
    router: typeof router
40
  }
41
}
42
43
ReactDOM.createRoot(document.getElementById("root")!).render(
44
  <StrictMode>
45
    <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
46
      <QueryClientProvider client={queryClient}>
47
        <RouterProvider router={router} />
48
        <Toaster richColors closeButton />
49
      </QueryClientProvider>
50
    </ThemeProvider>
51
  </StrictMode>,
52
)
53