Skip to content

Commit 65e77fd

Browse files
committed
chore: add an eCommerce starter example
1 parent 5ff65e0 commit 65e77fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+9747
-34
lines changed

example/ecommerce-starter/.cta.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"framework": "react",
3+
"typescript": true,
4+
"projectName": "ecommerce-starter",
5+
"mode": "file-router",
6+
"tailwind": true,
7+
"packageManager": "pnpm",
8+
"toolchain": "none",
9+
"variableValues": {},
10+
"git": true,
11+
"version": 1,
12+
"existingAddOns": [
13+
"tanchat",
14+
"start",
15+
"store"
16+
]
17+
}

example/ecommerce-starter/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local
6+
.output
7+
.vinxi

example/ecommerce-starter/README.md

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
Welcome to your new TanStack app!
2+
3+
# Getting Started
4+
5+
To run this application:
6+
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+
33+
34+
# TanStack Chat Application
35+
36+
Am example chat application built with TanStack Start, TanStack Store, and Claude AI.
37+
38+
## .env Updates
39+
40+
```env
41+
ANTHROPIC_API_KEY=your_anthropic_api_key
42+
```
43+
44+
## ✨ Features
45+
46+
### AI Capabilities
47+
- 🤖 Powered by Claude 3.5 Sonnet
48+
- 📝 Rich markdown formatting with syntax highlighting
49+
- 🎯 Customizable system prompts for tailored AI behavior
50+
- 🔄 Real-time message updates and streaming responses (coming soon)
51+
52+
### User Experience
53+
- 🎨 Modern UI with Tailwind CSS and Lucide icons
54+
- 🔍 Conversation management and history
55+
- 🔐 Secure API key management
56+
- 📋 Markdown rendering with code highlighting
57+
58+
### Technical Features
59+
- 📦 Centralized state management with TanStack Store
60+
- 🔌 Extensible architecture for multiple AI providers
61+
- 🛠️ TypeScript for type safety
62+
63+
## Architecture
64+
65+
### Tech Stack
66+
- **Frontend Framework**: TanStack Start
67+
- **Routing**: TanStack Router
68+
- **State Management**: TanStack Store
69+
- **Styling**: Tailwind CSS
70+
- **AI Integration**: Anthropic's Claude API
71+
72+
73+
## Routing
74+
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`.
75+
76+
### Adding A Route
77+
78+
To add a new route to your application just add another a new file in the `./src/routes` directory.
79+
80+
TanStack will automatically generate the content of the route file for you.
81+
82+
Now that you have two routes you can use a `Link` component to navigate between them.
83+
84+
### Adding Links
85+
86+
To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.
87+
88+
```tsx
89+
import { Link } from "@tanstack/react-router";
90+
```
91+
92+
Then anywhere in your JSX you can use it like so:
93+
94+
```tsx
95+
<Link to="/about">About</Link>
96+
```
97+
98+
This will create a link that will navigate to the `/about` route.
99+
100+
More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
101+
102+
### Using A Layout
103+
104+
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.
105+
106+
Here is an example layout that includes a header:
107+
108+
```tsx
109+
import { Outlet, createRootRoute } from '@tanstack/react-router'
110+
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
111+
112+
import { Link } from "@tanstack/react-router";
113+
114+
export const Route = createRootRoute({
115+
component: () => (
116+
<>
117+
<header>
118+
<nav>
119+
<Link to="/">Home</Link>
120+
<Link to="/about">About</Link>
121+
</nav>
122+
</header>
123+
<Outlet />
124+
<TanStackRouterDevtools />
125+
</>
126+
),
127+
})
128+
```
129+
130+
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
131+
132+
More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
133+
134+
135+
## Data Fetching
136+
137+
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.
138+
139+
For example:
140+
141+
```tsx
142+
const peopleRoute = createRoute({
143+
getParentRoute: () => rootRoute,
144+
path: "/people",
145+
loader: async () => {
146+
const response = await fetch("https://swapi.dev/api/people");
147+
return response.json() as Promise<{
148+
results: {
149+
name: string;
150+
}[];
151+
}>;
152+
},
153+
component: () => {
154+
const data = peopleRoute.useLoaderData();
155+
return (
156+
<ul>
157+
{data.results.map((person) => (
158+
<li key={person.name}>{person.name}</li>
159+
))}
160+
</ul>
161+
);
162+
},
163+
});
164+
```
165+
166+
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).
167+
168+
### React-Query
169+
170+
React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
171+
172+
First add your dependencies:
173+
174+
```bash
175+
pnpm add @tanstack/react-query @tanstack/react-query-devtools
176+
```
177+
178+
Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`.
179+
180+
```tsx
181+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
182+
183+
// ...
184+
185+
const queryClient = new QueryClient();
186+
187+
// ...
188+
189+
if (!rootElement.innerHTML) {
190+
const root = ReactDOM.createRoot(rootElement);
191+
192+
root.render(
193+
<QueryClientProvider client={queryClient}>
194+
<RouterProvider router={router} />
195+
</QueryClientProvider>
196+
);
197+
}
198+
```
199+
200+
You can also add TanStack Query Devtools to the root route (optional).
201+
202+
```tsx
203+
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
204+
205+
const rootRoute = createRootRoute({
206+
component: () => (
207+
<>
208+
<Outlet />
209+
<ReactQueryDevtools buttonPosition="top-right" />
210+
<TanStackRouterDevtools />
211+
</>
212+
),
213+
});
214+
```
215+
216+
Now you can use `useQuery` to fetch your data.
217+
218+
```tsx
219+
import { useQuery } from "@tanstack/react-query";
220+
221+
import "./App.css";
222+
223+
function App() {
224+
const { data } = useQuery({
225+
queryKey: ["people"],
226+
queryFn: () =>
227+
fetch("https://swapi.dev/api/people")
228+
.then((res) => res.json())
229+
.then((data) => data.results as { name: string }[]),
230+
initialData: [],
231+
});
232+
233+
return (
234+
<div>
235+
<ul>
236+
{data.map((person) => (
237+
<li key={person.name}>{person.name}</li>
238+
))}
239+
</ul>
240+
</div>
241+
);
242+
}
243+
244+
export default App;
245+
```
246+
247+
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).
248+
249+
## State Management
250+
251+
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.
252+
253+
First you need to add TanStack Store as a dependency:
254+
255+
```bash
256+
pnpm add @tanstack/store
257+
```
258+
259+
Now let's create a simple counter in the `src/App.tsx` file as a demonstration.
260+
261+
```tsx
262+
import { useStore } from "@tanstack/react-store";
263+
import { Store } from "@tanstack/store";
264+
import "./App.css";
265+
266+
const countStore = new Store(0);
267+
268+
function App() {
269+
const count = useStore(countStore);
270+
return (
271+
<div>
272+
<button onClick={() => countStore.setState((n) => n + 1)}>
273+
Increment - {count}
274+
</button>
275+
</div>
276+
);
277+
}
278+
279+
export default App;
280+
```
281+
282+
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.
283+
284+
Let's check this out by doubling the count using derived state.
285+
286+
```tsx
287+
import { useStore } from "@tanstack/react-store";
288+
import { Store, Derived } from "@tanstack/store";
289+
import "./App.css";
290+
291+
const countStore = new Store(0);
292+
293+
const doubledStore = new Derived({
294+
fn: () => countStore.state * 2,
295+
deps: [countStore],
296+
});
297+
doubledStore.mount();
298+
299+
function App() {
300+
const count = useStore(countStore);
301+
const doubledCount = useStore(doubledStore);
302+
303+
return (
304+
<div>
305+
<button onClick={() => countStore.setState((n) => n + 1)}>
306+
Increment - {count}
307+
</button>
308+
<div>Doubled - {doubledCount}</div>
309+
</div>
310+
);
311+
}
312+
313+
export default App;
314+
```
315+
316+
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.
317+
318+
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.
319+
320+
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).
321+
322+
# Demo files
323+
324+
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.
325+
326+
# Learn More
327+
328+
You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { defineConfig } from '@tanstack/react-start/config'
2+
import viteTsConfigPaths from 'vite-tsconfig-paths'
3+
import tailwindcss from '@tailwindcss/vite'
4+
5+
export default defineConfig({
6+
tsr: {
7+
appDirectory: 'src',
8+
},
9+
vite: {
10+
plugins: [
11+
// this is the plugin that enables path aliases
12+
viteTsConfigPaths({
13+
projects: ['./tsconfig.json'],
14+
}),
15+
tailwindcss(),
16+
],
17+
},
18+
})

0 commit comments

Comments
 (0)