Skip to content

Commit

Permalink
feat(tanstack-start): Path based routing and Router support (#3932)
Browse files Browse the repository at this point in the history
Co-authored-by: Joe Bell <[email protected]>
Co-authored-by: Stefanos Anagnostou <[email protected]>
Co-authored-by: Lennart <[email protected]>
  • Loading branch information
4 people authored Aug 26, 2024
1 parent 247b3fd commit b5c8ade
Show file tree
Hide file tree
Showing 58 changed files with 1,750 additions and 662 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-spiders-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/tanstack-start": minor
---

Add support for path based routing and TanStack Router only apps
3 changes: 3 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ actions:

integration:
- integration/**

tanstack:
- packages/tanstack-start/**
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ jobs:

strategy:
matrix:
test-name: ['generic', 'express', 'quickstart', 'ap-flows', 'elements', 'sessions', 'astro', 'expo-web']
test-name: ['generic', 'express', 'quickstart', 'ap-flows', 'elements', 'sessions', 'astro', 'expo-web', 'tanstack-start', 'tanstack-router']
test-project: ['chrome']
include:
- test-name: 'nextjs'
Expand Down
Empty file modified .husky/pre-commit
100644 → 100755
Empty file.
2 changes: 2 additions & 0 deletions integration/presets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createLongRunningApps } from './longRunningApps';
import { next } from './next';
import { react } from './react';
import { remix } from './remix';
import { tanstack } from './tanstack';

export const appConfigs = {
envs,
Expand All @@ -18,6 +19,7 @@ export const appConfigs = {
elements,
expo,
astro,
tanstack,
secrets: {
instanceKeys,
},
Expand Down
3 changes: 3 additions & 0 deletions integration/presets/longRunningApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { express } from './express';
import { next } from './next';
import { react } from './react';
import { remix } from './remix';
import { tanstack } from './tanstack';

/**
* A list of long-running applications that can be used in tests.
Expand All @@ -27,6 +28,8 @@ export const createLongRunningApps = () => {
{ id: 'astro.node.withCustomRoles', config: astro.node, env: envs.withCustomRoles },
{ id: 'astro.static.withCustomRoles', config: astro.static, env: envs.withCustomRoles },
{ id: 'expo.expo-web', config: expo.expoWeb, env: envs.withEmailCodes },
{ id: 'tanstack.start', config: tanstack.start, env: envs.withEmailCodes },
{ id: 'tanstack.router', config: tanstack.router, env: envs.withEmailCodes },
] as const;

const apps = configs.map(longRunningApplication);
Expand Down
33 changes: 33 additions & 0 deletions integration/presets/tanstack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { applicationConfig } from '../models/applicationConfig.js';
import { templates } from '../templates/index.js';

const clerkTanStackLocal = `file:${process.cwd()}/packages/tanstack-start`;

const router = applicationConfig()
.setName('tanstack-router')
.useTemplate(templates['tanstack-router'])
.setEnvFormatter('public', key => `VITE_${key}`)
// `--install-links` ensures that the @clerk/tanstack-start is installed as a regular dependancie instead of creating symlink
// please do not remove this flag as it's going to break the setup
.addScript('setup', 'npm i --install-links')
.addScript('dev', 'npm run dev')
.addScript('build', 'npm run build')
.addScript('serve', 'npm run start')
.addDependency('@clerk/tanstack-start', clerkTanStackLocal);

const start = applicationConfig()
.setName('tanstack-start')
.useTemplate(templates['tanstack-start'])
.setEnvFormatter('public', key => `VITE_${key}`)
// `--install-links` ensures that the @clerk/tanstack-start is installed as a regular dependancie instead of creating symlink
// please do not remove this flag as it's going to break the setup
.addScript('setup', 'npm i --install-links')
.addScript('dev', 'npm run dev')
.addScript('build', 'npm run build')
.addScript('serve', 'npm run start')
.addDependency('@clerk/tanstack-start', clerkTanStackLocal);

export const tanstack = {
start,
router,
} as const;
2 changes: 2 additions & 0 deletions integration/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const templates = {
'astro-node': resolve(__dirname, './astro-node'),
'astro-hybrid': resolve(__dirname, './astro-hybrid'),
'expo-web': resolve(__dirname, './expo-web'),
'tanstack-start': resolve(__dirname, './tanstack-start'),
'tanstack-router': resolve(__dirname, './tanstack-router'),
} as const;

if (new Set([...Object.values(templates)]).size !== Object.values(templates).length) {
Expand Down
10 changes: 10 additions & 0 deletions integration/templates/tanstack-router/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
6 changes: 6 additions & 0 deletions integration/templates/tanstack-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example

To run this example:

- `npm install` or `yarn`
- `npm start` or `yarn start`
30 changes: 30 additions & 0 deletions integration/templates/tanstack-router/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Vite App</title>
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/tailwindcss">
html {
color-scheme: light dark;
}
* {
@apply border-gray-200 dark:border-gray-800;
}
body {
@apply bg-gray-50 text-gray-950 dark:bg-gray-900 dark:text-gray-200;
}
</style>
</head>
<body>
<div id="app"></div>
<script
type="module"
src="/src/main.tsx"
></script>
</body>
</html>
24 changes: 24 additions & 0 deletions integration/templates/tanstack-router/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "tanstack-router-react-example-basic-file-based",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port=$PORT",
"build": "vite build",
"serve": "vite preview --port=$PORT",
"start": "vite"
},
"dependencies": {
"@tanstack/react-router": "^1.47.1",
"@tanstack/router-devtools": "^1.47.1",
"@tanstack/router-plugin": "^1.47.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.3.1",
"vite": "^5.3.5"
}
}
25 changes: 25 additions & 0 deletions integration/templates/tanstack-router/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

// Set up a Router instance
const router = createRouter({
routeTree,
defaultPreload: 'intent',
defaultStaleTime: 5000,
});

// Register things for typesafety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

const rootElement = document.getElementById('app')!;

if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement);
root.render(<RouterProvider router={router} />);
}
30 changes: 30 additions & 0 deletions integration/templates/tanstack-router/src/posts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { notFound } from '@tanstack/react-router';
import axios from 'redaxios';

export type PostType = {
id: string;
title: string;
body: string;
};

export const fetchPost = async (postId: string) => {
console.info(`Fetching post with id ${postId}...`);
await new Promise(r => setTimeout(r, 500));
const post = await axios
.get<PostType>(`https://jsonplaceholder.typicode.com/posts/${postId}`)
.then(r => r.data)
.catch(err => {
if (err.status === 404) {
throw notFound();
}
throw err;
});

return post;
};

export const fetchPosts = async () => {
console.info('Fetching posts...');
await new Promise(r => setTimeout(r, 500));
return axios.get<Array<PostType>>('https://jsonplaceholder.typicode.com/posts').then(r => r.data.slice(0, 10));
};
Loading

0 comments on commit b5c8ade

Please sign in to comment.