-
-
Notifications
You must be signed in to change notification settings - Fork 90
feat(examples): add AI-powered search example #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
136585d
aac2a30
aa1890e
98601a4
b1e31b4
720ebf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "projectName": "ts-react-search", | ||
| "mode": "file-router", | ||
| "typescript": true, | ||
| "tailwind": true, | ||
| "packageManager": "pnpm", | ||
| "addOnOptions": {}, | ||
| "git": true, | ||
| "version": 1, | ||
| "framework": "react-cra", | ||
| "chosenAddOns": ["nitro", "start"] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| node_modules | ||
| .DS_Store | ||
| dist | ||
| dist-ssr | ||
| *.local | ||
| count.txt | ||
| .env | ||
| .nitro | ||
| .tanstack | ||
| .wrangler | ||
| .output | ||
| .vinxi | ||
| todos.json |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "files.watcherExclude": { | ||
| "**/routeTree.gen.ts": true | ||
| }, | ||
| "search.exclude": { | ||
| "**/routeTree.gen.ts": true | ||
| }, | ||
| "files.readonlyInclude": { | ||
| "**/routeTree.gen.ts": true | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,287 @@ | ||||||
| Welcome to your new TanStack app! | ||||||
|
|
||||||
| # Getting Started | ||||||
|
|
||||||
| To run this application: | ||||||
|
|
||||||
| ```bash | ||||||
| pnpm install | ||||||
| pnpm start | ||||||
| ``` | ||||||
|
|
||||||
| # Building For Production | ||||||
|
|
||||||
| To build this application for production: | ||||||
|
|
||||||
| ```bash | ||||||
| pnpm build | ||||||
| ``` | ||||||
|
|
||||||
| ## Testing | ||||||
|
|
||||||
| This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with: | ||||||
|
|
||||||
| ```bash | ||||||
| pnpm test | ||||||
| ``` | ||||||
|
|
||||||
| ## Styling | ||||||
|
|
||||||
| This project uses [Tailwind CSS](https://tailwindcss.com/) for styling. | ||||||
|
|
||||||
| ## Routing | ||||||
|
|
||||||
| This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix hyphenation in compound modifier. Use "file-based router" instead of "file based router" when the compound adjective precedes a noun. 🔎 Proposed fix-This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`.
+This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file-based router. This means that the routes are managed as files in `src/routes`.Note: Also fixed the sentence fragment starting with "Which". 📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~34-~34: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### Adding A Route | ||||||
|
|
||||||
| To add a new route to your application just add another a new file in the `./src/routes` directory. | ||||||
|
|
||||||
| TanStack will automatically generate the content of the route file for you. | ||||||
|
|
||||||
| Now that you have two routes you can use a `Link` component to navigate between them. | ||||||
|
|
||||||
| ### Adding Links | ||||||
|
|
||||||
| To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`. | ||||||
|
|
||||||
| ```tsx | ||||||
| import { Link } from '@tanstack/react-router' | ||||||
| ``` | ||||||
|
|
||||||
| Then anywhere in your JSX you can use it like so: | ||||||
|
|
||||||
| ```tsx | ||||||
| <Link to="/about">About</Link> | ||||||
| ``` | ||||||
|
|
||||||
| This will create a link that will navigate to the `/about` route. | ||||||
|
|
||||||
| More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent). | ||||||
|
|
||||||
| ### Using A Layout | ||||||
|
|
||||||
| In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `<Outlet />` component. | ||||||
|
|
||||||
| Here is an example layout that includes a header: | ||||||
|
|
||||||
| ```tsx | ||||||
| import { Outlet, createRootRoute } from '@tanstack/react-router' | ||||||
| import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' | ||||||
|
|
||||||
| import { Link } from '@tanstack/react-router' | ||||||
|
|
||||||
| export const Route = createRootRoute({ | ||||||
| component: () => ( | ||||||
| <> | ||||||
| <header> | ||||||
| <nav> | ||||||
| <Link to="/">Home</Link> | ||||||
| <Link to="/about">About</Link> | ||||||
| </nav> | ||||||
| </header> | ||||||
| <Outlet /> | ||||||
| <TanStackRouterDevtools /> | ||||||
| </> | ||||||
| ), | ||||||
| }) | ||||||
| ``` | ||||||
|
|
||||||
| The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout. | ||||||
|
|
||||||
| More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts). | ||||||
|
|
||||||
| ## Data Fetching | ||||||
|
|
||||||
| There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered. | ||||||
|
|
||||||
| For example: | ||||||
|
|
||||||
| ```tsx | ||||||
| const peopleRoute = createRoute({ | ||||||
| getParentRoute: () => rootRoute, | ||||||
| path: '/people', | ||||||
| loader: async () => { | ||||||
| const response = await fetch('https://swapi.dev/api/people') | ||||||
| return response.json() as Promise<{ | ||||||
| results: { | ||||||
| name: string | ||||||
| }[] | ||||||
| }> | ||||||
| }, | ||||||
| component: () => { | ||||||
| const data = peopleRoute.useLoaderData() | ||||||
| return ( | ||||||
| <ul> | ||||||
| {data.results.map((person) => ( | ||||||
| <li key={person.name}>{person.name}</li> | ||||||
| ))} | ||||||
| </ul> | ||||||
| ) | ||||||
| }, | ||||||
| }) | ||||||
| ``` | ||||||
|
|
||||||
| Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters). | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix hyphenation in compound modifier. Use "data-fetching logic" with a hyphen when the compound adjective precedes a noun. 🔎 Proposed fix-Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).
+Loaders simplify your data-fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~125-~125: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### React-Query | ||||||
|
|
||||||
| React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix typo in documentation. "you application" should be "your application". 🔎 Proposed fix-React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
+React-Query is an excellent addition or alternative to route loading and integrating it into your application is a breeze.📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~129-~129: Ensure spelling is correct (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| First add your dependencies: | ||||||
|
|
||||||
| ```bash | ||||||
| pnpm add @tanstack/react-query @tanstack/react-query-devtools | ||||||
| ``` | ||||||
|
|
||||||
| Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`. | ||||||
|
|
||||||
| ```tsx | ||||||
| import { QueryClient, QueryClientProvider } from '@tanstack/react-query' | ||||||
|
|
||||||
| // ... | ||||||
|
|
||||||
| const queryClient = new QueryClient() | ||||||
|
|
||||||
| // ... | ||||||
|
|
||||||
| if (!rootElement.innerHTML) { | ||||||
| const root = ReactDOM.createRoot(rootElement) | ||||||
|
|
||||||
| root.render( | ||||||
| <QueryClientProvider client={queryClient}> | ||||||
| <RouterProvider router={router} /> | ||||||
| </QueryClientProvider>, | ||||||
| ) | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| You can also add TanStack Query Devtools to the root route (optional). | ||||||
|
|
||||||
| ```tsx | ||||||
| import { ReactQueryDevtools } from '@tanstack/react-query-devtools' | ||||||
|
|
||||||
| const rootRoute = createRootRoute({ | ||||||
| component: () => ( | ||||||
| <> | ||||||
| <Outlet /> | ||||||
| <ReactQueryDevtools buttonPosition="top-right" /> | ||||||
| <TanStackRouterDevtools /> | ||||||
| </> | ||||||
| ), | ||||||
| }) | ||||||
| ``` | ||||||
|
|
||||||
| Now you can use `useQuery` to fetch your data. | ||||||
|
|
||||||
| ```tsx | ||||||
| import { useQuery } from '@tanstack/react-query' | ||||||
|
|
||||||
| import './App.css' | ||||||
|
|
||||||
| function App() { | ||||||
| const { data } = useQuery({ | ||||||
| queryKey: ['people'], | ||||||
| queryFn: () => | ||||||
| fetch('https://swapi.dev/api/people') | ||||||
| .then((res) => res.json()) | ||||||
| .then((data) => data.results as { name: string }[]), | ||||||
| initialData: [], | ||||||
| }) | ||||||
|
|
||||||
| return ( | ||||||
| <div> | ||||||
| <ul> | ||||||
| {data.map((person) => ( | ||||||
| <li key={person.name}>{person.name}</li> | ||||||
| ))} | ||||||
| </ul> | ||||||
| </div> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| export default App | ||||||
| ``` | ||||||
|
|
||||||
| You can find out everything you need to know on how to use React-Query in the [React-Query documentation](https://tanstack.com/query/latest/docs/framework/react/overview). | ||||||
|
|
||||||
| ## State Management | ||||||
|
|
||||||
| Another common requirement for React applications is state management. There are many options for state management in React. TanStack Store provides a great starting point for your project. | ||||||
|
|
||||||
| First you need to add TanStack Store as a dependency: | ||||||
|
|
||||||
| ```bash | ||||||
| pnpm add @tanstack/store | ||||||
| ``` | ||||||
|
|
||||||
| Now let's create a simple counter in the `src/App.tsx` file as a demonstration. | ||||||
|
|
||||||
| ```tsx | ||||||
| import { useStore } from '@tanstack/react-store' | ||||||
| import { Store } from '@tanstack/store' | ||||||
| import './App.css' | ||||||
|
|
||||||
| const countStore = new Store(0) | ||||||
|
|
||||||
| function App() { | ||||||
| const count = useStore(countStore) | ||||||
| return ( | ||||||
| <div> | ||||||
| <button onClick={() => countStore.setState((n) => n + 1)}> | ||||||
| Increment - {count} | ||||||
| </button> | ||||||
| </div> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| export default App | ||||||
| ``` | ||||||
|
|
||||||
| One of the many nice features of TanStack Store is the ability to derive state from other state. That derived state will update when the base state updates. | ||||||
|
|
||||||
| Let's check this out by doubling the count using derived state. | ||||||
|
|
||||||
| ```tsx | ||||||
| import { useStore } from '@tanstack/react-store' | ||||||
| import { Store, Derived } from '@tanstack/store' | ||||||
| import './App.css' | ||||||
|
|
||||||
| const countStore = new Store(0) | ||||||
|
|
||||||
| const doubledStore = new Derived({ | ||||||
| fn: () => countStore.state * 2, | ||||||
| deps: [countStore], | ||||||
| }) | ||||||
| doubledStore.mount() | ||||||
|
|
||||||
| function App() { | ||||||
| const count = useStore(countStore) | ||||||
| const doubledCount = useStore(doubledStore) | ||||||
|
|
||||||
| return ( | ||||||
| <div> | ||||||
| <button onClick={() => countStore.setState((n) => n + 1)}> | ||||||
| Increment - {count} | ||||||
| </button> | ||||||
| <div>Doubled - {doubledCount}</div> | ||||||
| </div> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| export default App | ||||||
| ``` | ||||||
|
|
||||||
| We use the `Derived` class to create a new store that is derived from another store. The `Derived` class has a `mount` method that will start the derived store updating. | ||||||
|
|
||||||
| Once we've created the derived store we can use it in the `App` component just like we would any other store using the `useStore` hook. | ||||||
|
|
||||||
| You can find out everything you need to know on how to use TanStack Store in the [TanStack Store documentation](https://tanstack.com/store/latest). | ||||||
|
|
||||||
| # Demo files | ||||||
|
|
||||||
| Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed. | ||||||
|
|
||||||
| # Learn More | ||||||
|
|
||||||
| You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com). | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,55 @@ | ||||||
| { | ||||||
| "name": "ts-react-search", | ||||||
| "private": true, | ||||||
| "type": "module", | ||||||
| "scripts": { | ||||||
| "dev": "vite dev --port 3000", | ||||||
| "build": "vite build", | ||||||
| "serve": "vite preview", | ||||||
| "test": "exit 0" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test script is a placeholder and doesn't run actual tests. Line 9 shows 🔎 Proposed fix to run actual tests- "test": "exit 0"
+ "test": "vitest run"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| }, | ||||||
| "dependencies": { | ||||||
| "@radix-ui/react-slot": "^1.2.4", | ||||||
| "@tailwindcss/vite": "^4.1.18", | ||||||
| "@tanstack/ai": "workspace:*", | ||||||
| "@tanstack/ai-openai": "workspace:*", | ||||||
| "@tanstack/ai-react": "workspace:*", | ||||||
| "@tanstack/query-db-collection": "^1.0.6", | ||||||
| "@tanstack/react-db": "^0.1.55", | ||||||
| "@tanstack/react-devtools": "^0.8.2", | ||||||
| "@tanstack/react-query": "^5.90.12", | ||||||
| "@tanstack/react-router": "^1.141.1", | ||||||
| "@tanstack/react-router-devtools": "^1.139.7", | ||||||
| "@tanstack/react-router-ssr-query": "^1.139.7", | ||||||
| "@tanstack/react-start": "^1.141.1", | ||||||
| "@tanstack/router-plugin": "^1.139.7", | ||||||
| "@tanstack/zod-adapter": "^1.140.1", | ||||||
| "class-variance-authority": "^0.7.1", | ||||||
| "clsx": "^2.1.1", | ||||||
| "lucide-react": "^0.561.0", | ||||||
| "nitro": "latest", | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Pin the nitro dependency version. Line 30 specifies 🔎 Recommended fix to pin the versionAfter determining the current latest version, update to: - "nitro": "latest",
+ "nitro": "^2.x.x",Replace
🤖 Prompt for AI Agents |
||||||
| "radix-ui": "^1.4.3", | ||||||
| "react": "^19.2.3", | ||||||
| "react-day-picker": "^9.12.0", | ||||||
| "react-dom": "^19.2.3", | ||||||
| "tailwind-merge": "^3.4.0", | ||||||
| "tailwindcss": "^4.1.18", | ||||||
| "tw-animate-css": "^1.4.0", | ||||||
| "vite-tsconfig-paths": "^5.1.4", | ||||||
| "zod": "^4.2.0" | ||||||
| }, | ||||||
| "devDependencies": { | ||||||
| "@tanstack/devtools-vite": "^0.3.11", | ||||||
| "@testing-library/dom": "^10.4.1", | ||||||
| "@testing-library/react": "^16.3.0", | ||||||
| "@types/node": "^24.10.1", | ||||||
| "@types/react": "^19.2.7", | ||||||
| "@types/react-dom": "^19.2.3", | ||||||
| "@vitejs/plugin-react": "^5.1.2", | ||||||
| "jsdom": "^27.2.0", | ||||||
| "typescript": "5.9.3", | ||||||
| "vite": "^7.2.7", | ||||||
| "vitest": "^4.0.14", | ||||||
| "web-vitals": "^5.1.0" | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Framework declaration inconsistent with actual setup.
The configuration specifies
"framework": "react-cra"(Create React App), but the project uses Vite with TanStack Start (as shown in vite.config.ts). This appears to be stale scaffolding metadata.Consider either updating to
"framework": "vite-react"or removing this configuration file if it's not actively used by tooling.🤖 Prompt for AI Agents