Skip to content

Commit 84e43e0

Browse files
committed
feat(example): adjust readme of tanstack start and add script on package.json in root to start app
1 parent c40eb63 commit 84e43e0

File tree

3 files changed

+11
-278
lines changed

3 files changed

+11
-278
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
OPENAI_API_KEY=
2+
Lines changed: 8 additions & 278 deletions
Original file line numberDiff line numberDiff line change
@@ -1,287 +1,17 @@
1-
Welcome to your new TanStack app!
1+
# Realtime TanStack Start Demo
22

3-
# Getting Started
3+
This example shows how to combine TanStack Start with the OpenAI Agents SDK to create a realtime voice agent using TanStack Router for routing.
44

5-
To run this application:
5+
## Run the example
66

7-
```bash
8-
pnpm install
9-
pnpm start
10-
```
11-
12-
# Building For Production
13-
14-
To build this application for production:
15-
16-
```bash
17-
pnpm build
18-
```
19-
20-
## Testing
21-
22-
This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with:
23-
24-
```bash
25-
pnpm test
26-
```
27-
28-
## Styling
29-
30-
This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
31-
32-
## Routing
33-
34-
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`.
35-
36-
### Adding A Route
37-
38-
To add a new route to your application just add another a new file in the `./src/routes` directory.
39-
40-
TanStack will automatically generate the content of the route file for you.
41-
42-
Now that you have two routes you can use a `Link` component to navigate between them.
43-
44-
### Adding Links
45-
46-
To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.
47-
48-
```tsx
49-
import { Link } from '@tanstack/react-router';
50-
```
51-
52-
Then anywhere in your JSX you can use it like so:
53-
54-
```tsx
55-
<Link to="/about">About</Link>
56-
```
57-
58-
This will create a link that will navigate to the `/about` route.
59-
60-
More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
61-
62-
### Using A Layout
63-
64-
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.
65-
66-
Here is an example layout that includes a header:
67-
68-
```tsx
69-
import { Outlet, createRootRoute } from '@tanstack/react-router';
70-
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
71-
72-
import { Link } from '@tanstack/react-router';
73-
74-
export const Route = createRootRoute({
75-
component: () => (
76-
<>
77-
<header>
78-
<nav>
79-
<Link to="/">Home</Link>
80-
<Link to="/about">About</Link>
81-
</nav>
82-
</header>
83-
<Outlet />
84-
<TanStackRouterDevtools />
85-
</>
86-
),
87-
});
88-
```
89-
90-
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
91-
92-
More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
93-
94-
## Data Fetching
95-
96-
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.
97-
98-
For example:
99-
100-
```tsx
101-
const peopleRoute = createRoute({
102-
getParentRoute: () => rootRoute,
103-
path: '/people',
104-
loader: async () => {
105-
const response = await fetch('https://swapi.dev/api/people');
106-
return response.json() as Promise<{
107-
results: {
108-
name: string;
109-
}[];
110-
}>;
111-
},
112-
component: () => {
113-
const data = peopleRoute.useLoaderData();
114-
return (
115-
<ul>
116-
{data.results.map((person) => (
117-
<li key={person.name}>{person.name}</li>
118-
))}
119-
</ul>
120-
);
121-
},
122-
});
123-
```
124-
125-
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).
126-
127-
### React-Query
128-
129-
React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
130-
131-
First add your dependencies:
132-
133-
```bash
134-
pnpm add @tanstack/react-query @tanstack/react-query-devtools
135-
```
136-
137-
Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`.
138-
139-
```tsx
140-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
141-
142-
// ...
143-
144-
const queryClient = new QueryClient();
145-
146-
// ...
147-
148-
if (!rootElement.innerHTML) {
149-
const root = ReactDOM.createRoot(rootElement);
150-
151-
root.render(
152-
<QueryClientProvider client={queryClient}>
153-
<RouterProvider router={router} />
154-
</QueryClientProvider>,
155-
);
156-
}
157-
```
158-
159-
You can also add TanStack Query Devtools to the root route (optional).
160-
161-
```tsx
162-
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
163-
164-
const rootRoute = createRootRoute({
165-
component: () => (
166-
<>
167-
<Outlet />
168-
<ReactQueryDevtools buttonPosition="top-right" />
169-
<TanStackRouterDevtools />
170-
</>
171-
),
172-
});
173-
```
174-
175-
Now you can use `useQuery` to fetch your data.
176-
177-
```tsx
178-
import { useQuery } from '@tanstack/react-query';
179-
180-
import './App.css';
181-
182-
function App() {
183-
const { data } = useQuery({
184-
queryKey: ['people'],
185-
queryFn: () =>
186-
fetch('https://swapi.dev/api/people')
187-
.then((res) => res.json())
188-
.then((data) => data.results as { name: string }[]),
189-
initialData: [],
190-
});
191-
192-
return (
193-
<div>
194-
<ul>
195-
{data.map((person) => (
196-
<li key={person.name}>{person.name}</li>
197-
))}
198-
</ul>
199-
</div>
200-
);
201-
}
202-
203-
export default App;
204-
```
205-
206-
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).
207-
208-
## State Management
209-
210-
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.
211-
212-
First you need to add TanStack Store as a dependency:
7+
Set the `OPENAI_API_KEY` environment variable and run:
2138

2149
```bash
215-
pnpm add @tanstack/store
216-
```
217-
218-
Now let's create a simple counter in the `src/App.tsx` file as a demonstration.
219-
220-
```tsx
221-
import { useStore } from '@tanstack/react-store';
222-
import { Store } from '@tanstack/store';
223-
import './App.css';
224-
225-
const countStore = new Store(0);
226-
227-
function App() {
228-
const count = useStore(countStore);
229-
return (
230-
<div>
231-
<button onClick={() => countStore.setState((n) => n + 1)}>
232-
Increment - {count}
233-
</button>
234-
</div>
235-
);
236-
}
237-
238-
export default App;
10+
pnpm examples:realtime-tantsack-start
23911
```
24012

241-
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.
242-
243-
Let's check this out by doubling the count using derived state.
244-
245-
```tsx
246-
import { useStore } from '@tanstack/react-store';
247-
import { Store, Derived } from '@tanstack/store';
248-
import './App.css';
249-
250-
const countStore = new Store(0);
251-
252-
const doubledStore = new Derived({
253-
fn: () => countStore.state * 2,
254-
deps: [countStore],
255-
});
256-
doubledStore.mount();
257-
258-
function App() {
259-
const count = useStore(countStore);
260-
const doubledCount = useStore(doubledStore);
261-
262-
return (
263-
<div>
264-
<button onClick={() => countStore.setState((n) => n + 1)}>
265-
Increment - {count}
266-
</button>
267-
<div>Doubled - {doubledCount}</div>
268-
</div>
269-
);
270-
}
271-
272-
export default App;
273-
```
274-
275-
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.
276-
277-
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.
278-
279-
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).
280-
281-
# Demo files
282-
283-
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.
13+
Open [http://localhost:3000](http://localhost:3000) in your browser and start talking.
28414

285-
# Learn More
15+
## Endpoints
28616

287-
You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).
17+
- **`/`** – Realtime voice demo with agent handoffs, tools, and guardrails using the `RealtimeSession` class. Code in `src/routes/index.tsx`.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"examples:customer-service": "pnpm -F customer-service start",
3333
"examples:realtime-demo": "pnpm -F realtime-demo dev",
3434
"examples:realtime-next": "pnpm -F realtime-next dev",
35+
"examples:realtime-tantsack-start": "pnpm -F realtime-tantsack-start dev",
3536
"examples:research-bot": "pnpm -F research-bot start",
3637
"examples:financial-research-agent": "pnpm -F financial-research-agent start",
3738
"examples:tools-computer-use": "pnpm -F tools start:computer-use",

0 commit comments

Comments
 (0)