Conversation
📝 WalkthroughWalkthroughThis PR introduces a new TanStack Start example project demonstrating Ory authentication integration, featuring routing infrastructure, protected routes with authentication guards, server-side session management, and a complete React UI with login/logout functionality. Changes
Sequence DiagramsequenceDiagram
participant Browser as Browser
participant App as TanStack Start App
participant OryServer as Ory Server
participant SessionCache as Session Cache
Browser->>App: Navigate to protected route
App->>App: Route beforeLoad hook executes
App->>App: Call getOrySession()
App->>SessionCache: Check cache for session
alt Cache hit
SessionCache-->>App: Return cached session
else Cache miss or expired
App->>OryServer: GET /sessions/whoami (with cookie)
OryServer-->>App: Return session data
App->>SessionCache: Store session (TTL: 10 min)
end
App->>App: Evaluate isAuthenticated
alt Authenticated
App->>Browser: Render protected route
Browser->>App: User clicks logout
App->>App: Call getLogoutUrl()
App->>OryServer: POST /self-service/logout/flows (with cookie)
OryServer-->>App: Return logout_url
App->>Browser: Redirect to logout_url
else Not authenticated
App->>Browser: Redirect to login URL
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@examples/react/start-basic-ory/package.json`:
- Around line 12-19: The TanStack packages in package.json are pinned to
published versions causing potential desync; update the internal dependencies
"@tanstack/react-router", "@tanstack/react-router-devtools", and
"@tanstack/react-start" to use the workspace protocol (workspace:*) instead of
the fixed versions so local workspace packages are used during development and
CI.
In `@examples/react/start-basic-ory/src/router.tsx`:
- Around line 5-10: The defaultErrorComponent passed into createRouter currently
renders err.error.stack which can leak internals; update the
defaultErrorComponent (used in createRouter) to check the environment (e.g.,
process.env.NODE_ENV === 'development') and only render the full stack in
development, otherwise render a safe generic message (or err.error.message
minimally) and handle missing error gracefully; change the function referenced
as defaultErrorComponent to perform this conditional rendering using
ErrorComponentProps.error.
In `@examples/react/start-basic-ory/src/routes/__root.tsx`:
- Around line 11-13: Alphabetize the named imports and separate the type-only
import onto its own line: change the named import from
getOrySession,getLogoutUrl to getLogoutUrl,getOrySession (from
'~/utils/orySession') and move type { OrySession } into a dedicated type-only
import line (import type { OrySession } from '~/utils/orySession'); keep appCss
import first. This fixes the sort-imports/import/order warnings referencing
getOrySession, getLogoutUrl, and OrySession.
In `@examples/react/start-basic-ory/src/routes/_authenticated.tsx`:
- Line 1: The named imports from '@tanstack/react-router' are not in the order
expected by ESLint's sort-imports rule; reorder the import specifiers
(createFileRoute, Outlet, redirect) so they are sorted alphabetically
(case-insensitive) per the rule, update the import statement using the sorted
order, and re-run lint to confirm the warning is resolved; look for and modify
the import line that currently imports createFileRoute, Outlet, redirect.
In `@examples/react/start-basic-ory/src/routes/index.tsx`:
- Line 1: The file references React.CSSProperties (at the use of inlineStyles or
similar around the symbol React.CSSProperties) without importing React, causing
strict TypeScript to fail; add a type-only import "import type { CSSProperties }
from 'react'" at the top and replace uses of React.CSSProperties with the
imported CSSProperties type (or use CSSProperties directly where the type is
declared) so the code compiles under strict mode.
🧹 Nitpick comments (1)
examples/react/start-basic-ory/src/utils/orySession.ts (1)
12-35: Prevent unbounded cache growth by pruning expired entries.
sessionCacheonly evicts the current key, so unique cookies can accumulate over time. A small prune step keeps memory bounded.♻️ Suggested change
const SESSION_CACHE_TTL = 600_000 // 10 minutes const sessionCache = new Map<string, { data: Session | null; expiresAt: number }>() + +const pruneSessionCache = () => { + const now = Date.now() + for (const [key, entry] of sessionCache) { + if (entry.expiresAt <= now) { + sessionCache.delete(key) + } + } +} export const getOrySession = createServerFn({ method: 'GET' }).handler(async () => { const req = getRequest() const cookie = req.headers.get('cookie') ?? '' + + pruneSessionCache() const cached = sessionCache.get(cookie) if (cached && Date.now() < cached.expiresAt) { return cached.data }
| "dependencies": { | ||
| "@ory/client-fetch": "^1.22.22", | ||
| "@tanstack/react-router": "^1.158.0", | ||
| "@tanstack/react-router-devtools": "^1.158.0", | ||
| "@tanstack/react-start": "^1.158.0", | ||
| "react": "^19.0.0", | ||
| "react-dom": "^19.0.0", | ||
| "zod": "^3.24.2" |
There was a problem hiding this comment.
Use workspace:* for internal TanStack dependencies.
Pinning internal packages to published versions can desync the example from the workspace during local dev and CI. Please switch the TanStack packages to the workspace protocol.
🔧 Suggested change
- "@tanstack/react-router": "^1.158.0",
- "@tanstack/react-router-devtools": "^1.158.0",
- "@tanstack/react-start": "^1.158.0",
+ "@tanstack/react-router": "workspace:*",
+ "@tanstack/react-router-devtools": "workspace:*",
+ "@tanstack/react-start": "workspace:*",As per coding guidelines: **/package.json: Use workspace protocol workspace:* for internal dependencies in package.json files.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "dependencies": { | |
| "@ory/client-fetch": "^1.22.22", | |
| "@tanstack/react-router": "^1.158.0", | |
| "@tanstack/react-router-devtools": "^1.158.0", | |
| "@tanstack/react-start": "^1.158.0", | |
| "react": "^19.0.0", | |
| "react-dom": "^19.0.0", | |
| "zod": "^3.24.2" | |
| "dependencies": { | |
| "@ory/client-fetch": "^1.22.22", | |
| "@tanstack/react-router": "workspace:*", | |
| "@tanstack/react-router-devtools": "workspace:*", | |
| "@tanstack/react-start": "workspace:*", | |
| "react": "^19.0.0", | |
| "react-dom": "^19.0.0", | |
| "zod": "^3.24.2" |
🤖 Prompt for AI Agents
In `@examples/react/start-basic-ory/package.json` around lines 12 - 19, The
TanStack packages in package.json are pinned to published versions causing
potential desync; update the internal dependencies "@tanstack/react-router",
"@tanstack/react-router-devtools", and "@tanstack/react-start" to use the
workspace protocol (workspace:*) instead of the fixed versions so local
workspace packages are used during development and CI.
| const router = createRouter({ | ||
| routeTree, | ||
| defaultPreload: 'intent', | ||
| defaultErrorComponent: (err) => <p>{err.error.stack}</p>, | ||
| defaultNotFoundComponent: () => <p>not found</p>, | ||
| scrollRestoration: true, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, locate and read the router file
find . -type f -path "*examples/react/start-basic-ory/src/router.tsx"Repository: TanStack/router
Length of output: 106
🏁 Script executed:
# Get the actual file content around lines 5-10
head -20 examples/react/start-basic-ory/src/router.tsxRepository: TanStack/router
Length of output: 546
🏁 Script executed:
# Check if this is a Vite project (to verify import.meta.env availability)
cat examples/react/start-basic-ory/package.json | head -30Repository: TanStack/router
Length of output: 866
🏁 Script executed:
# Search for other error handling patterns in the codebase
rg "defaultErrorComponent|error\.stack" --type tsx --type ts | head -20Repository: TanStack/router
Length of output: 86
🏁 Script executed:
# Check the error object structure in TanStack Router documentation or type definitions
rg "defaultErrorComponent" --type ts -A 3 | head -40Repository: TanStack/router
Length of output: 2323
🏁 Script executed:
# Check if ESLint router plugin is installed
cat examples/react/start-basic-ory/package.json | rg -i "eslint|router"Repository: TanStack/router
Length of output: 151
🏁 Script executed:
# Search for error handling in other examples
find examples -name "*.tsx" -o -name "*.ts" | xargs grep -l "defaultErrorComponent" 2>/dev/null | head -5Repository: TanStack/router
Length of output: 309
🏁 Script executed:
# Check the start-bare example router configuration
cat examples/react/start-bare/src/router.tsxRepository: TanStack/router
Length of output: 546
🏁 Script executed:
# Search for type definitions or interface for defaultErrorComponent
rg "interface.*ErrorComponent|type.*ErrorComponent" --type ts | head -20Repository: TanStack/router
Length of output: 2557
🏁 Script executed:
# Check the exact error parameter signature in React Router package
rg "defaultErrorComponent.*\(" packages/react-router/src -A 2 | head -30Repository: TanStack/router
Length of output: 41
🏁 Script executed:
# Find React Router's ErrorComponentProps definition
rg "ErrorComponentProps" packages/react-router/src -A 5 | head -40Repository: TanStack/router
Length of output: 1135
🏁 Script executed:
# Check how error is structured in React Router
rg "error.*stack|Error.*stack" packages/react-router/src -B 2 -A 2 | head -40Repository: TanStack/router
Length of output: 1209
🏁 Script executed:
# Look for type definitions in react-router
find packages/react-router -name "*.ts" -o -name "*.tsx" | xargs grep -l "interface.*ErrorComponent\|type.*ErrorComponent" 2>/dev/nullRepository: TanStack/router
Length of output: 146
🏁 Script executed:
# Find ErrorComponentProps definition in router-core
rg "interface ErrorComponentProps|type ErrorComponentProps" packages/router-core/src -A 3Repository: TanStack/router
Length of output: 318
🏁 Script executed:
# Check the error structure in router-core
rg "error.*Error\|Error.*{" packages/router-core/src -B 2 -A 2 | grep -A 5 "error:"Repository: TanStack/router
Length of output: 166
Avoid exposing stack traces in production.
Rendering error.stack directly can leak internal details. The defaultErrorComponent receives ErrorComponentProps with an error property; stack traces should be shown only in development and a generic message in production.
🔒 Proposed fix
- defaultErrorComponent: (err) => <p>{err.error.stack}</p>,
+ defaultErrorComponent: ({ error }) =>
+ import.meta.env.DEV ? (
+ <pre>{error.stack}</pre>
+ ) : (
+ <p>Something went wrong.</p>
+ ),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const router = createRouter({ | |
| routeTree, | |
| defaultPreload: 'intent', | |
| defaultErrorComponent: (err) => <p>{err.error.stack}</p>, | |
| defaultNotFoundComponent: () => <p>not found</p>, | |
| scrollRestoration: true, | |
| const router = createRouter({ | |
| routeTree, | |
| defaultPreload: 'intent', | |
| defaultErrorComponent: ({ error }) => | |
| import.meta.env.DEV ? ( | |
| <pre>{error.stack}</pre> | |
| ) : ( | |
| <p>Something went wrong.</p> | |
| ), | |
| defaultNotFoundComponent: () => <p>not found</p>, | |
| scrollRestoration: true, |
🤖 Prompt for AI Agents
In `@examples/react/start-basic-ory/src/router.tsx` around lines 5 - 10, The
defaultErrorComponent passed into createRouter currently renders err.error.stack
which can leak internals; update the defaultErrorComponent (used in
createRouter) to check the environment (e.g., process.env.NODE_ENV ===
'development') and only render the full stack in development, otherwise render a
safe generic message (or err.error.message minimally) and handle missing error
gracefully; change the function referenced as defaultErrorComponent to perform
this conditional rendering using ErrorComponentProps.error.
| import appCss from '~/styles/app.css?url' | ||
| import { getOrySession, getLogoutUrl } from '~/utils/orySession' | ||
| import type { OrySession } from '~/utils/orySession' |
There was a problem hiding this comment.
Resolve ESLint import ordering warnings.
sort-imports and import/order are flagging the orySession import member order and the type-only import placement.
🧹 Proposed fix
-import appCss from '~/styles/app.css?url'
-import { getOrySession, getLogoutUrl } from '~/utils/orySession'
-import type { OrySession } from '~/utils/orySession'
+import { getLogoutUrl, getOrySession, type OrySession } from '~/utils/orySession'
+import appCss from '~/styles/app.css?url'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import appCss from '~/styles/app.css?url' | |
| import { getOrySession, getLogoutUrl } from '~/utils/orySession' | |
| import type { OrySession } from '~/utils/orySession' | |
| import { getLogoutUrl, getOrySession, type OrySession } from '~/utils/orySession' | |
| import appCss from '~/styles/app.css?url' |
🧰 Tools
🪛 ESLint
[error] 12-12: Member 'getLogoutUrl' of the import declaration should be sorted alphabetically.
(sort-imports)
[error] 13-13: ~/utils/orySession type import should occur before import of ~/styles/app.css?url
(import/order)
🤖 Prompt for AI Agents
In `@examples/react/start-basic-ory/src/routes/__root.tsx` around lines 11 - 13,
Alphabetize the named imports and separate the type-only import onto its own
line: change the named import from getOrySession,getLogoutUrl to
getLogoutUrl,getOrySession (from '~/utils/orySession') and move type {
OrySession } into a dedicated type-only import line (import type { OrySession }
from '~/utils/orySession'); keep appCss import first. This fixes the
sort-imports/import/order warnings referencing getOrySession, getLogoutUrl, and
OrySession.
| @@ -0,0 +1,12 @@ | |||
| import { createFileRoute, Outlet, redirect } from '@tanstack/react-router' | |||
There was a problem hiding this comment.
Fix ESLint import member ordering.
sort-imports is flagging member order in the router import. Reorder to satisfy lint.
🧹 Proposed fix
-import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'
+import { Outlet, createFileRoute, redirect } from '@tanstack/react-router'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { createFileRoute, Outlet, redirect } from '@tanstack/react-router' | |
| import { Outlet, createFileRoute, redirect } from '@tanstack/react-router' |
🧰 Tools
🪛 ESLint
[error] 1-1: Member 'Outlet' of the import declaration should be sorted alphabetically.
(sort-imports)
🤖 Prompt for AI Agents
In `@examples/react/start-basic-ory/src/routes/_authenticated.tsx` at line 1, The
named imports from '@tanstack/react-router' are not in the order expected by
ESLint's sort-imports rule; reorder the import specifiers (createFileRoute,
Outlet, redirect) so they are sorted alphabetically (case-insensitive) per the
rule, update the import statement using the sorted order, and re-run lint to
confirm the warning is resolved; look for and modify the import line that
currently imports createFileRoute, Outlet, redirect.
| @@ -0,0 +1,194 @@ | |||
| import { createFileRoute } from '@tanstack/react-router' | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's locate and examine the file in question
fd -type f -name "index.tsx" | grep "start-basic-ory" | head -5Repository: TanStack/router
Length of output: 229
🏁 Script executed:
# Also check the overall repository structure to understand context
git ls-files "examples/react/start-basic-ory/" | head -20Repository: TanStack/router
Length of output: 861
🏁 Script executed:
# Look for tsconfig files
fd -type f -name "tsconfig*.json" | head -10Repository: TanStack/router
Length of output: 229
🏁 Script executed:
# Read the index.tsx file
cat -n examples/react/start-basic-ory/src/routes/index.tsxRepository: TanStack/router
Length of output: 6239
🏁 Script executed:
# Read the tsconfig.json
cat -n examples/react/start-basic-ory/tsconfig.jsonRepository: TanStack/router
Length of output: 743
🏁 Script executed:
# Check root tsconfig if it exists
cat -n tsconfig.json 2>/dev/null | head -50Repository: TanStack/router
Length of output: 1042
Import React types for CSSProperties.
React.CSSProperties is referenced at line 67 without importing React. With strict mode enabled and no allowUmdGlobalAccess configured, this will fail TypeScript compilation. Add a type-only import of CSSProperties from react and use it directly.
Proposed fix
import { createFileRoute } from '@tanstack/react-router'
+import type { CSSProperties } from 'react'
export const Route = createFileRoute('/')({
component: RouteComponent,
})
const badges = ['File-based Routing', 'Server Functions', 'Session Auth', 'Protected Routes']
function RouteComponent() {
return (
<main style={styles.page}>
...
</main>
)
}
-const styles: Record<string, React.CSSProperties> = {
+const styles: Record<string, CSSProperties> = {🤖 Prompt for AI Agents
In `@examples/react/start-basic-ory/src/routes/index.tsx` at line 1, The file
references React.CSSProperties (at the use of inlineStyles or similar around the
symbol React.CSSProperties) without importing React, causing strict TypeScript
to fail; add a type-only import "import type { CSSProperties } from 'react'" at
the top and replace uses of React.CSSProperties with the imported CSSProperties
type (or use CSSProperties directly where the type is declared) so the code
compiles under strict mode.
Summary
Adds a new example (
examples/react/start-basic-ory) demonstrating how to wireOry Kratos identity management into a TanStack Start app using file-based routing.
What's in the example
beforeLoadcalls a serverfunction to fetch the active Ory session and publishes it as
AuthContext.Child routes read it with
Route.useRouteContext()— no global state storeneeded.
_authenticated.tsxguardsits children (currently
/profile) by checkingcontext.auth.isAuthenticatedin
beforeLoadand redirecting to the Ory login flow if the session is missing.src/utils/orySession.tsusescreateServerFnto proxy session and logout requests to Kratos. Ory SDKcredentials and cookies never touch the client bundle.
navigation within the TTL window.
ory tunnel(no Docker, cloud-backed)docker-composequickstartDependencies added
Only
@ory/client-fetch(the official Ory SDK) is added. Everything else is already in the TanStack Start baseline (react,vite,@tanstack/*).Summary by CodeRabbit
New Features
Documentation