Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions docs/docs/00100-intro/00200-quickstarts/00152-astro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
title: Astro Quickstart
sidebar_label: Astro
slug: /quickstarts/astro
hide_table_of_contents: true
---

import { InstallCardLink } from "@site/src/components/InstallCardLink";
import { StepByStep, Step, StepText, StepCode } from "@site/src/components/Steps";


Get a SpacetimeDB Astro app running in under 5 minutes.

## Prerequisites

- [Node.js](https://nodejs.org/) 18+ installed
- [SpacetimeDB CLI](https://spacetimedb.com/install) installed

<InstallCardLink />

---

<StepByStep>
<Step title="Create your project">
<StepText>
Run the `spacetime dev` command to create a new project with a SpacetimeDB module and Astro client.

This will start the local SpacetimeDB server, publish your module, generate TypeScript bindings, and start the Astro development server.
</StepText>
<StepCode>
```bash
spacetime dev --template astro-ts
```
</StepCode>
</Step>

<Step title="Open your app">
<StepText>
Navigate to [http://localhost:4321](http://localhost:4321) to see your app running.

The Astro app reads `SPACETIMEDB_*` variables on the server and `PUBLIC_SPACETIMEDB_*` variables in the client, so `.env.local` can configure both sides of the app.
</StepText>
</Step>

<Step title="Explore the project structure">
<StepText>
Your project contains both server and client code using Astro SSR and a live React island for real-time updates.

Edit `spacetimedb/src/index.ts` to add tables and reducers. Edit `src/pages/index.astro` and `src/components/PersonList.tsx` to build your UI.
</StepText>
<StepCode>
```text
my-astro-app/
├── spacetimedb/ # Your SpacetimeDB module
│ └── src/
│ └── index.ts # SpacetimeDB module logic
├── src/
│ ├── components/
│ │ ├── PersonList.tsx
│ │ ├── SpacetimeApp.tsx
│ │ └── DeferredPeopleSnapshot.astro
│ ├── lib/
│ │ └── spacetimedb-server.ts
│ ├── module_bindings/ # Auto-generated types
│ ├── layouts/
│ │ └── Layout.astro
│ ├── pages/
│ │ └── index.astro
│ └── styles/
│ └── global.css
└── package.json
```
</StepCode>
</Step>

<Step title="Understand tables and reducers">
<StepText>
Open `spacetimedb/src/index.ts` to see the module code. The template includes a `person` table and two reducers: `add` to insert a person, and `sayHello` to greet everyone.

Tables store your data. Reducers are functions that modify data and are the only way to write to the database.
</StepText>
<StepCode>
```typescript
import { schema, table, t } from 'spacetimedb/server';

const spacetimedb = schema({
person: table(
{ public: true },
{
name: t.string(),
}
),
});
export default spacetimedb;

export const add = spacetimedb.reducer(
{ name: t.string() },
(ctx, { name }) => {
ctx.db.person.insert({ name });
}
);

export const sayHello = spacetimedb.reducer(ctx => {
for (const person of ctx.db.person.iter()) {
console.info(`Hello, ${person.name}!`);
}
console.info('Hello, World!');
});
```
</StepCode>
</Step>

<Step title="Test with the CLI">
<StepText>
Open a new terminal and navigate to your project directory. Then use the SpacetimeDB CLI to call reducers and query your data directly.
</StepText>
<StepCode>
```bash
cd my-spacetime-app

# Call the add reducer to insert a person
spacetime call add Alice

# Query the person table
spacetime sql "SELECT * FROM person"
name
---------
"Alice"

# Call sayHello to greet everyone
spacetime call say_hello

# View the module logs
spacetime logs
2025-01-13T12:00:00.000000Z INFO: Hello, Alice!
2025-01-13T12:00:00.000000Z INFO: Hello, World!
```
</StepCode>
</Step>

<Step title="Understand Astro SSR and real-time hydration">
<StepText>
The SpacetimeDB SDK works both server-side and client-side. The template uses a hybrid approach:

- **Astro page** (`src/pages/index.astro`): Fetches initial data on the server for a fast first render
- **React island** (`src/components/SpacetimeApp.tsx`): Hydrates on the client and provides the SpacetimeDB connection
- **Live table UI** (`src/components/PersonList.tsx`): Uses `useTable()` and `useReducer()` for real-time updates
</StepText>
<StepCode>
```astro
---
import Layout from '../layouts/Layout.astro';
import SpacetimeApp from '../components/SpacetimeApp';
import { fetchPeople } from '../lib/spacetimedb-server';

const initialPeople = await fetchPeople();
---

<Layout title="astro-ts">
<h1>astro-ts</h1>
<SpacetimeApp client:load initialPeople={initialPeople} />
</Layout>
```
</StepCode>
</Step>

<Step title="Understand Astro server islands">
<StepText>
The template also includes a deferred Astro-only section to demonstrate `server:defer`.

`src/components/DeferredPeopleSnapshot.astro` fetches its own server-rendered snapshot, and `src/pages/index.astro` renders it as a server island without changing the main real-time client flow.
</StepText>
<StepCode>
```astro
<DeferredPeopleSnapshot server:defer>
<div slot="fallback">Loading deferred people snapshot…</div>
</DeferredPeopleSnapshot>
```
</StepCode>
</Step>
</StepByStep>
28 changes: 28 additions & 0 deletions templates/astro-ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# build output
dist/
spacetimedb/dist/

# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# environment variables
.env
.env.local
.env.*.local
.env.production

# macOS-specific files
.DS_Store

# jetbrains setting folder
.idea/

13 changes: 13 additions & 0 deletions templates/astro-ts/.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"description": "Astro app with a TypeScript server module",
"client_framework": "Astro",
"client_lang": "typescript",
"server_lang": "typescript",
"builtWith": [
"astro",
"react",
"react-dom",
"typescript",
"spacetimedb"
]
}
1 change: 1 addition & 0 deletions templates/astro-ts/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../licenses/apache2.txt
137 changes: 137 additions & 0 deletions templates/astro-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
Get a SpacetimeDB Astro app running in under 5 minutes.

## Prerequisites

- [Node.js](https://nodejs.org/) 18+ installed
- [SpacetimeDB CLI](https://spacetimedb.com/install) installed

Install the [SpacetimeDB CLI](https://spacetimedb.com/install) before continuing.

---

## Create your project

Run the `spacetime dev` command to create a new project with a SpacetimeDB module and Astro client.

This will start the local SpacetimeDB server, publish your module, generate TypeScript bindings, and start the Astro development server.

```bash
spacetime dev --template astro-ts
```

## Open your app

Navigate to [http://localhost:4321](http://localhost:4321) to see your app running.

The Astro app reads `SPACETIMEDB_*` variables on the server and `PUBLIC_SPACETIMEDB_*` variables in the client, so `.env.local` can configure both sides of the app.

## Explore the project structure

Your project contains both server and client code using Astro SSR and a live interactive client for real-time updates.

Edit `spacetimedb/src/index.ts` to add tables and reducers. Edit `src/pages/index.astro` and `src/components/PersonList.tsx` to build your UI.

```text
my-astro-app/
├── spacetimedb/ # Your SpacetimeDB module
│ └── src/
│ └── index.ts # SpacetimeDB module logic
├── src/
│ ├── components/
│ │ ├── PersonList.tsx
│ │ ├── SpacetimeApp.tsx
│ │ └── DeferredPeopleSnapshot.astro
│ ├── lib/
│ │ └── spacetimedb-server.ts
│ ├── module_bindings/ # Auto-generated types
│ ├── layouts/
│ │ └── Layout.astro
│ ├── pages/
│ │ └── index.astro
│ └── styles/
│ └── global.css
└── package.json
```

## Understand tables and reducers

Open `spacetimedb/src/index.ts` to see the module code. The template includes a `person` table and two reducers: `add` to insert a person, and `sayHello` to greet everyone.

Tables store your data. Reducers are functions that modify data and are the only way to write to the database.

```typescript
import { schema, table, t } from 'spacetimedb/server';

const spacetimedb = schema({
person: table(
{ public: true },
{
name: t.string(),
}
),
});
export default spacetimedb;

export const add = spacetimedb.reducer(
{ name: t.string() },
(ctx, { name }) => {
ctx.db.person.insert({ name });
}
);

export const sayHello = spacetimedb.reducer(ctx => {
for (const person of ctx.db.person.iter()) {
console.info(`Hello, ${person.name}!`);
}
console.info('Hello, World!');
});
```

## Understand Astro SSR plus real-time hydration

The template uses a hybrid rendering model:

- `src/pages/index.astro` fetches the initial list of people on the server for a fast first paint.
- `src/components/SpacetimeApp.tsx` hydrates with `client:load` and provides the SpacetimeDB connection.
- `src/components/PersonList.tsx` subscribes to the `person` table with `useTable()` and calls reducers with `useReducer()`.

This gives you server-rendered HTML on the first request and a live WebSocket-backed UI after hydration.

## Understand Astro server islands

The template also includes a deferred Astro-only section to demonstrate `server:defer`.

- `src/components/DeferredPeopleSnapshot.astro` fetches its own server-rendered snapshot.
- `src/pages/index.astro` renders it with `server:defer`, so it loads after the main page shell.

This demonstrates an Astro-specific pattern without affecting the main real-time client flow.

## Test with the CLI

Open a new terminal and navigate to your project directory. Then use the SpacetimeDB CLI to call reducers and query your data directly.

```bash
cd my-spacetime-app

# Call the add reducer to insert a person
spacetime call add Alice

# Query the person table
spacetime sql "SELECT * FROM person"
name
---------
"Alice"

# Call sayHello to greet everyone
spacetime call say_hello

# View the module logs
spacetime logs
2025-01-13T12:00:00.000000Z INFO: Hello, Alice!
2025-01-13T12:00:00.000000Z INFO: Hello, World!
```

## Next steps

- See the [Chat App Tutorial](https://spacetimedb.com/docs/intro/tutorials/chat-app) for a complete example
- Read the [TypeScript SDK Reference](https://spacetimedb.com/docs/intro/core-concepts/clients/typescript-reference) for detailed API docs
12 changes: 12 additions & 0 deletions templates/astro-ts/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-check
import node from '@astrojs/node';
import react from '@astrojs/react';
import { defineConfig } from 'astro/config';

export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone',
}),
integrations: [react()],
});
Loading