Skip to content

Commit

Permalink
TSR (#199)
Browse files Browse the repository at this point in the history
* tsr + vinxi init

* checkpoint

* Fix rebase

* update deps

* match.handle => match.staticData

* checkpoint

* fix: link ssr and client router (#167)

* fix: upgrade deps

* feat: checkpoint

* fix: upgrade deps

* fix: upgrade deps, remove unnecessary default error boundaries

* fix: html level headers support

* checkpoint

* checkpoint

* checkpoint

* checkpoint

* make build work with latest vinxi (#189)

Co-authored-by: Tanner Linsley <[email protected]>

* fix: upgrade deps

* no build command

* output directory

* deploy

* TanStack Start Teaser

* fix: migrate all routes

* use real packages

* fix: add TanStack Start

* No index for tsr branch

* rebase

* cjs crap

* fix colors, add scroll restoration, fix docsearch

* fix: framework/version picker

* give prism some mb-4

* fix: ranger => query type

* fix: config get started link

* fix: type errors

* cleanup

* update deps

* fix: upgrade deps

* fix: upgrade deps

* fix: sidebar collapsing and the content badge hitting the link content (#198)

* fix: sidebar having content collapsing

* fix: sidebar framework badge colliding with the page title/name

* feat codesplitting

* fix: documentation upgrade, better 404s, organization

---------

Co-authored-by: Lachlan Collins <[email protected]>
Co-authored-by: Nikhil Saraf <[email protected]>
Co-authored-by: Sean Cassiere <[email protected]>
  • Loading branch information
4 people authored Apr 2, 2024
1 parent 507e0f4 commit 093f2a7
Show file tree
Hide file tree
Showing 195 changed files with 14,143 additions and 7,163 deletions.
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": ["react-app"],
"parser": "@typescript-eslint/parser",
"plugins": ["react-hooks"]
}
12 changes: 0 additions & 12 deletions .eslintrc.cjs

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ yarn.lock
.env
.vercel
.output
.vinxi

/build/
/api/
/server/build
/public/build
.vinxi
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Welcome to TanStack.com!

This site is built with Remix!
This site is built with TanStack Router!

- [Remix Docs](https://remix.run/docs)
- [TanStack Router Docs](https://tanstack.com/router)

It's deployed automagically with Vercel!

Expand All @@ -21,7 +21,7 @@ This starts your app in development mode, rebuilding assets on file changes.

## Editing and previewing the docs of TanStack projects locally

The documentations for all TanStack projects except for `React Charts` are hosted on [https://tanstack.com](https://tanstack.com), powered by this Remix app.
The documentations for all TanStack projects except for `React Charts` are hosted on [https://tanstack.com](https://tanstack.com), powered by this TanStack Router app.
In production, the markdown doc pages are fetched from the GitHub repos of the projects, but in development they are read from the local file system.

Follow these steps if you want to edit the doc pages of a project (in these steps we'll assume it's [`TanStack/form`](https://github.com/tanstack/form)) and preview them locally :
Expand Down
129 changes: 129 additions & 0 deletions app.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { createApp } from 'vinxi'
import reactRefresh from '@vitejs/plugin-react'
import { serverFunctions } from '@vinxi/server-functions/plugin'
import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
import { config } from 'vinxi/plugins/config'
import tsconfigPaths from 'vite-tsconfig-paths'
import { serverTransform } from '@vinxi/server-functions/server'
import { normalize } from 'vinxi/lib/path'
import { resolve } from 'import-meta-resolve'
import path from 'path'
import { fileURLToPath } from 'url'

const customVite = () =>
config('dev', (router, app, env) => ({
// ssr: {
// noExternal: [/react-router-server\/dist\/esm\/server-runtime/],
// },
optimizeDeps: {
include: [
'node_modules@tanstack/react-router-server/**/*.js',
'react-icons',
],
},
resolve:
env.command !== 'build'
? {
dedupe: [
'react',
'react-dom',
'@tanstack/store',
'@tanstack/react-store',
'@tanstack/react-router',
'@tanstack/react-router-server',
'@tanstack/react-cross-context',
'@tanstack/history',
'use-sync-external-store',
],
}
: {},
// plugins: [
// {
// name: 'inline-env-vars-as-prefix',
// // Write the env vars for some specific keys into the bundle at the very beginning of the file
// // using a (globalThis || window).tsr_env object.
// intro: `(globalThis || window).ROUTER_NAME = import.meta.env.ROUTER_NAME`,
// },
// ],
}))

export default createApp({
server: {
preset: 'vercel',
experimental: {
asyncStorage: true,
asyncContext: true,
},
},
routers: [
{
name: 'public',
type: 'static',
dir: './public',
base: '/',
},
{
name: 'ssr',
type: 'http',
handler: './app/server.tsx',
target: 'server',
plugins: () => [
TanStackRouterVite({
experimental: {
enableCodeSplitting: true,
},
}),
customVite(),
tsconfigPaths(),
serverTransform({
runtime: `@tanstack/react-router-server/server-runtime`,
}),
reactRefresh(),
],
link: {
client: 'client',
},
},
{
name: 'client',
type: 'client',
handler: './app/client.tsx',
target: 'browser',
base: '/_build',
plugins: () => [
TanStackRouterVite({
experimental: {
enableCodeSplitting: true,
},
}),
customVite(),
tsconfigPaths(),
serverFunctions.client({
runtime: `@tanstack/react-router-server/client-runtime`,
}),
reactRefresh(),
],
},
serverFunctions.router({
name: 'server',
plugins: () => [customVite(), tsconfigPaths()],
handler: resolveToRelative(
'@tanstack/react-router-server/server-handler'
),
runtime: `@tanstack/react-router-server/server-runtime`,
}),
],
})

function resolveToRelative(p) {
const toAbsolute = (file) => file.split('://').at(-1)

const resolved = toAbsolute(resolve(p, import.meta.url))

const relative = path.relative(
path.resolve(toAbsolute(import.meta.url), '..'),
resolved
)

return relative
}
76 changes: 76 additions & 0 deletions app/auth/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { createCookie } from '@remix-run/node'
import { redirect } from '@tanstack/react-router'

let secret = process.env.COOKIE_SECRET || 'default'
if (secret === 'default') {
console.warn(
'🚨 No COOKIE_SECRET environment variable set, using default. The app is insecure in production.'
)
secret = 'default-secret'
}

let cookie = createCookie('auth', {
secrets: [secret],
// 30 days
maxAge: 30 * 24 * 60 * 60,
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
})

export async function getAuthFromRequest(
request: Request
): Promise<string | null> {
const c = request.headers.get('Cookie')
let userId = await cookie.parse(c)
return userId ?? null
}

export async function setAuthOnResponse(
response: Response,
userId: string
): Promise<Response> {
let header = await cookie.serialize(userId)
response.headers.append('Set-Cookie', header)
return response
}

export async function requireAuthCookie(request: Request) {
let userId = await getAuthFromRequest(request)
if (!userId) {
throw redirect({
to: '/login',
headers: {
'Set-Cookie': await cookie.serialize('', {
maxAge: 0,
}),
},
})
}
return userId
}

export async function redirectIfLoggedInLoader({
request,
}: {
request: Request
}) {
let userId = await getAuthFromRequest(request)
if (userId) {
throw redirect({
to: '/',
})
}
return null
}

export async function redirectWithClearedCookie() {
return redirect({
to: '/',
headers: {
'Set-Cookie': await cookie.serialize(null, {
expires: new Date(0),
}),
},
})
}
13 changes: 13 additions & 0 deletions app/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// <reference types="vinxi/types/client" />
import { hydrateRoot } from 'react-dom/client'
import 'vinxi/client'

import { createRouter } from './router'
import { StartClient } from '@tanstack/react-router-server'

const router = createRouter()

const app = <StartClient router={router} />

router.hydrate()
hydrateRoot(document, app)
6 changes: 4 additions & 2 deletions app/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { FaCopy } from 'react-icons/fa'
import { svelteHighlighter } from '~/utils/svelteHighlighter'
// Add back additional language support after `prism-react` upgrade
;(typeof global !== 'undefined' ? global : window).Prism = Prism
require('prismjs/components/prism-diff')
require('prismjs/components/prism-bash')
// @ts-expect-error
import('prismjs/components/prism-diff')
// @ts-expect-error
import('prismjs/components/prism-bash')

// @ts-ignore Alias markup as vue highlight
Prism.languages.vue = Prism.languages.markup
Expand Down
93 changes: 52 additions & 41 deletions app/components/DefaultCatchBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,66 @@
import { Link } from '@remix-run/react'
import {
ErrorComponent,
ErrorComponentProps,
Link,
rootRouteId,
useMatch,
useRouter,
} from '@tanstack/react-router'

type DefaultCatchBoundaryType = {
status: number
statusText: string
data: string
isRoot?: boolean
}
// type DefaultCatchBoundaryType = {
// status: number
// statusText: string
// data: string
// isRoot?: boolean
// }

export function DefaultCatchBoundary({
status,
statusText,
data,
isRoot,
}: DefaultCatchBoundaryType) {
let message
switch (status) {
case 401:
message = (
<p>
Oops! Looks like you tried to visit a page that you do not have access
to.
</p>
)
break
case 404:
message = (
<p>Oops! Looks like you tried to visit a page that does not exist.</p>
)
break
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
const router = useRouter()
const isRoot = useMatch({
strict: false,
select: (state) => state.id === rootRouteId,
})

default:
throw new Error(data || statusText)
}
console.error(error)

return (
<div className="flex-1 p-4 flex flex-col items-center justify-center gap-6">
<h1 className="opacity-10 flex flex-col text-center font-black">
<div className="text-7xl leading-none">{status}</div>
{/* <div className="text-7xl leading-none">{status}</div>
{statusText ? (
<div className="text-3xl leading-none">{statusText}</div>
) : null}
) : null} */}
</h1>
{message ? <div className="text-lg">{message}</div> : null}
{isRoot ? (
<Link
to="/"
className={`py-2 px-4 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
<ErrorComponent error={error} />
<div className="flex gap-2 items-center flex-wrap">
<button
onClick={() => {
router.invalidate()
}}
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
>
TanStack Home
</Link>
) : null}
Try Again
</button>
{isRoot ? (
<Link
to="/"
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
>
TanStack Home
</Link>
) : (
<Link
to="/"
className={`px-2 py-1 bg-gray-600 dark:bg-gray-700 rounded text-white uppercase font-extrabold`}
onClick={(e) => {
e.preventDefault()
window.history.back()
}}
>
Go Back
</Link>
)}
</div>
</div>
)
}
Loading

0 comments on commit 093f2a7

Please sign in to comment.