WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 77eb22f

Browse files
📝 Add docstrings to start-basic-netlify
Docstrings generation was requested by @TomasBankauskas. * #6071 (comment) The following files were modified: * `examples/react/start-basic-netlify/src/components/DefaultCatchBoundary.tsx` * `examples/react/start-basic-netlify/src/components/NotFound.tsx` * `examples/react/start-basic-netlify/src/components/PostError.tsx` * `examples/react/start-basic-netlify/src/components/UserError.tsx` * `examples/react/start-basic-netlify/src/router.tsx` * `examples/react/start-basic-netlify/src/routes/__root.tsx` * `examples/react/start-basic-netlify/src/routes/_pathlessLayout.tsx` * `examples/react/start-basic-netlify/src/routes/_pathlessLayout/_nested-layout.tsx` * `examples/react/start-basic-netlify/src/routes/_pathlessLayout/_nested-layout/route-a.tsx` * `examples/react/start-basic-netlify/src/routes/_pathlessLayout/_nested-layout/route-b.tsx` * `examples/react/start-basic-netlify/src/routes/deferred.tsx` * `examples/react/start-basic-netlify/src/routes/index.tsx` * `examples/react/start-basic-netlify/src/routes/posts.$postId.tsx` * `examples/react/start-basic-netlify/src/routes/posts.index.tsx` * `examples/react/start-basic-netlify/src/routes/posts.tsx` * `examples/react/start-basic-netlify/src/routes/posts_.$postId.deep.tsx` * `examples/react/start-basic-netlify/src/routes/users.$userId.tsx` * `examples/react/start-basic-netlify/src/routes/users.index.tsx` * `examples/react/start-basic-netlify/src/routes/users.tsx`
1 parent bcce02c commit 77eb22f

File tree

19 files changed

+706
-0
lines changed

19 files changed

+706
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
ErrorComponent,
3+
Link,
4+
rootRouteId,
5+
useMatch,
6+
useRouter,
7+
} from '@tanstack/react-router'
8+
import type { ErrorComponentProps } from '@tanstack/react-router'
9+
10+
/**
11+
* Render a default error UI for a caught route error with controls to retry or navigate.
12+
*
13+
* Logs the provided error to the console and renders an ErrorComponent alongside buttons
14+
* to invalidate the router (retry) and either navigate home or go back in history depending
15+
* on whether the current match is the root route.
16+
*
17+
* @param error - The caught error provided to the catch boundary
18+
* @returns A React element displaying the error and action controls to retry or navigate
19+
*/
20+
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
21+
const router = useRouter()
22+
const isRoot = useMatch({
23+
strict: false,
24+
select: (state) => state.id === rootRouteId,
25+
})
26+
27+
console.error('DefaultCatchBoundary Error:', error)
28+
29+
return (
30+
<div className="min-w-0 flex-1 p-4 flex flex-col items-center justify-center gap-6">
31+
<ErrorComponent error={error} />
32+
<div className="flex gap-2 items-center flex-wrap">
33+
<button
34+
onClick={() => {
35+
router.invalidate()
36+
}}
37+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded-sm text-white uppercase font-extrabold`}
38+
>
39+
Try Again
40+
</button>
41+
{isRoot ? (
42+
<Link
43+
to="/"
44+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded-sm text-white uppercase font-extrabold`}
45+
>
46+
Home
47+
</Link>
48+
) : (
49+
<Link
50+
to="/"
51+
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded-sm text-white uppercase font-extrabold`}
52+
onClick={(e) => {
53+
e.preventDefault()
54+
window.history.back()
55+
}}
56+
>
57+
Go Back
58+
</Link>
59+
)}
60+
</div>
61+
</div>
62+
)
63+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Link } from '@tanstack/react-router'
2+
3+
/**
4+
* Render a simple "not found" view that shows an optional message and two navigation actions.
5+
*
6+
* @param children - Optional custom content to display instead of the default "The page you are looking for does not exist." message.
7+
* @returns A React element containing the message area and two controls: a "Go back" button (calls history.back) and a "Start Over" link to the root path.
8+
*/
9+
export function NotFound({ children }: { children?: React.ReactNode }) {
10+
return (
11+
<div className="space-y-2 p-2">
12+
<div className="text-gray-600 dark:text-gray-400">
13+
{children || <p>The page you are looking for does not exist.</p>}
14+
</div>
15+
<p className="flex items-center gap-2 flex-wrap">
16+
<button
17+
onClick={() => window.history.back()}
18+
className="bg-emerald-500 text-white px-2 py-1 rounded-sm uppercase font-black text-sm"
19+
>
20+
Go back
21+
</button>
22+
<Link
23+
to="/"
24+
className="bg-cyan-600 text-white px-2 py-1 rounded-sm uppercase font-black text-sm"
25+
>
26+
Start Over
27+
</Link>
28+
</p>
29+
</div>
30+
)
31+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ErrorComponent } from '@tanstack/react-router'
2+
import type { ErrorComponentProps } from '@tanstack/react-router'
3+
4+
/**
5+
* Displays the given routing error.
6+
*
7+
* @param error - The error object provided by the router for the failed route.
8+
* @returns A JSX element that renders the error UI.
9+
*/
10+
export function PostErrorComponent({ error }: ErrorComponentProps) {
11+
return <ErrorComponent error={error} />
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ErrorComponent } from '@tanstack/react-router'
2+
import type { ErrorComponentProps } from '@tanstack/react-router'
3+
4+
/**
5+
* Renders an error UI for a routing error.
6+
*
7+
* @param error - The error object produced during route handling to display to the user.
8+
* @returns The rendered error UI element.
9+
*/
10+
export function UserErrorComponent({ error }: ErrorComponentProps) {
11+
return <ErrorComponent error={error} />
12+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createRouter } from '@tanstack/react-router'
2+
import { routeTree } from './routeTree.gen'
3+
import { DefaultCatchBoundary } from './components/DefaultCatchBoundary'
4+
import { NotFound } from './components/NotFound'
5+
6+
/**
7+
* Create and return a configured TanStack React Router instance for the application.
8+
*
9+
* @returns A router configured with the application's `routeTree`, intent preloading, `DefaultCatchBoundary` as the default error component, `NotFound` as the default not-found component, and scroll restoration enabled.
10+
*/
11+
export function getRouter() {
12+
const router = createRouter({
13+
routeTree,
14+
defaultPreload: 'intent',
15+
defaultErrorComponent: DefaultCatchBoundary,
16+
defaultNotFoundComponent: () => <NotFound />,
17+
scrollRestoration: true,
18+
})
19+
return router
20+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/// <reference types="vite/client" />
2+
import {
3+
HeadContent,
4+
Link,
5+
Scripts,
6+
createRootRoute,
7+
} from '@tanstack/react-router'
8+
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
9+
import * as React from 'react'
10+
import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary'
11+
import { NotFound } from '~/components/NotFound'
12+
import appCss from '~/styles/app.css?url'
13+
import { seo } from '~/utils/seo'
14+
15+
export const Route = createRootRoute({
16+
head: () => ({
17+
meta: [
18+
{
19+
charSet: 'utf-8',
20+
},
21+
{
22+
name: 'viewport',
23+
content: 'width=device-width, initial-scale=1',
24+
},
25+
...seo({
26+
title:
27+
'TanStack Start | Type-Safe, Client-First, Full-Stack React Framework',
28+
description: `TanStack Start is a type-safe, client-first, full-stack React framework. `,
29+
}),
30+
],
31+
links: [
32+
{ rel: 'stylesheet', href: appCss },
33+
{
34+
rel: 'apple-touch-icon',
35+
sizes: '180x180',
36+
href: '/apple-touch-icon.png',
37+
},
38+
{
39+
rel: 'icon',
40+
type: 'image/png',
41+
sizes: '32x32',
42+
href: '/favicon-32x32.png',
43+
},
44+
{
45+
rel: 'icon',
46+
type: 'image/png',
47+
sizes: '16x16',
48+
href: '/favicon-16x16.png',
49+
},
50+
{ rel: 'manifest', href: '/site.webmanifest', color: '#fffff' },
51+
{ rel: 'icon', href: '/favicon.ico' },
52+
],
53+
scripts: [
54+
{
55+
src: '/customScript.js',
56+
type: 'text/javascript',
57+
},
58+
],
59+
}),
60+
errorComponent: DefaultCatchBoundary,
61+
notFoundComponent: () => <NotFound />,
62+
shellComponent: RootDocument,
63+
})
64+
65+
/**
66+
* Render the application's HTML document shell with global navigation and injected head/scripts.
67+
*
68+
* Renders a complete HTML structure including HeadContent, a top navigation bar of internal links,
69+
* a content outlet for `children`, the TanStack Router Devtools, and Scripts.
70+
*
71+
* @param children - Routed content to render inside the document body
72+
* @returns The root HTML document element that wraps routed content and provides head, navigation, devtools, and scripts
73+
*/
74+
function RootDocument({ children }: { children: React.ReactNode }) {
75+
return (
76+
<html>
77+
<head>
78+
<HeadContent />
79+
</head>
80+
<body>
81+
<div className="p-2 flex gap-2 text-lg">
82+
<Link
83+
to="/"
84+
activeProps={{
85+
className: 'font-bold',
86+
}}
87+
activeOptions={{ exact: true }}
88+
>
89+
Home
90+
</Link>{' '}
91+
<Link
92+
to="/posts"
93+
activeProps={{
94+
className: 'font-bold',
95+
}}
96+
>
97+
Posts
98+
</Link>{' '}
99+
<Link
100+
to="/users"
101+
activeProps={{
102+
className: 'font-bold',
103+
}}
104+
>
105+
Users
106+
</Link>{' '}
107+
<Link
108+
to="/route-a"
109+
activeProps={{
110+
className: 'font-bold',
111+
}}
112+
>
113+
Pathless Layout
114+
</Link>{' '}
115+
<Link
116+
to="/deferred"
117+
activeProps={{
118+
className: 'font-bold',
119+
}}
120+
>
121+
Deferred
122+
</Link>{' '}
123+
<Link
124+
// @ts-expect-error
125+
to="/this-route-does-not-exist"
126+
activeProps={{
127+
className: 'font-bold',
128+
}}
129+
>
130+
This Route Does Not Exist
131+
</Link>
132+
</div>
133+
<hr />
134+
{children}
135+
<TanStackRouterDevtools position="bottom-right" />
136+
<Scripts />
137+
</body>
138+
</html>
139+
)
140+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Outlet, createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/_pathlessLayout')({
4+
component: LayoutComponent,
5+
})
6+
7+
/**
8+
* Layout component that renders a header and an Outlet for nested routes.
9+
*
10+
* @returns A JSX element containing a container with a top header and an <Outlet /> for nested route content.
11+
*/
12+
function LayoutComponent() {
13+
return (
14+
<div className="p-2">
15+
<div className="border-b">I'm a layout</div>
16+
<div>
17+
<Outlet />
18+
</div>
19+
</div>
20+
)
21+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Link, Outlet, createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/_pathlessLayout/_nested-layout')({
4+
component: LayoutComponent,
5+
})
6+
7+
/**
8+
* Renders a nested layout with a header, two navigation links (Route A and Route B), and an Outlet for nested route content.
9+
*
10+
* @returns The JSX element containing the layout header, navigation links with active styling, and an Outlet for child routes.
11+
*/
12+
function LayoutComponent() {
13+
return (
14+
<div>
15+
<div>I'm a nested layout</div>
16+
<div className="flex gap-2 border-b">
17+
<Link
18+
to="/route-a"
19+
activeProps={{
20+
className: 'font-bold',
21+
}}
22+
>
23+
Go to route A
24+
</Link>
25+
<Link
26+
to="/route-b"
27+
activeProps={{
28+
className: 'font-bold',
29+
}}
30+
>
31+
Go to route B
32+
</Link>
33+
</div>
34+
<div>
35+
<Outlet />
36+
</div>
37+
</div>
38+
)
39+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/_pathlessLayout/_nested-layout/route-a')(
4+
{
5+
component: LayoutAComponent,
6+
},
7+
)
8+
9+
/**
10+
* Renders the layout A component showing "I'm A!".
11+
*
12+
* @returns A JSX element containing a div with the text "I'm A!".
13+
*/
14+
function LayoutAComponent() {
15+
return <div>I'm A!</div>
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/_pathlessLayout/_nested-layout/route-b')(
4+
{
5+
component: LayoutBComponent,
6+
},
7+
)
8+
9+
/**
10+
* Renders a simple layout component that displays "I'm B!".
11+
*
12+
* @returns A JSX element containing a `div` with the text "I'm B!".
13+
*/
14+
function LayoutBComponent() {
15+
return <div>I'm B!</div>
16+
}

0 commit comments

Comments
 (0)