Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
db1ecce
feat: added nuxt module
Dec 10, 2025
e5c95ac
feat: add Nuxt Supabase Todo List demo with environment configuration…
Dec 15, 2025
3521b82
feat: prepare NuxtPowerSyncDatabase to support default sync client im…
Dec 15, 2025
c58db3c
feat: add environment configuration template and sync rules for Nuxt …
Dec 15, 2025
5771c58
feat: add README and update seed.sql for Nuxt Supabase Todo List demo
Dec 15, 2025
07a9c27
docs: update README with secure password note and correct PowerSync d…
Jan 12, 2026
7c52649
feat: add powersync-icon.svg asset and update references in AppHeader…
Jan 12, 2026
a67886d
chore: update package.json to include @supabase/supabase-js in depend…
Jan 12, 2026
d67a0fe
chore: remove vite-plugin-top-level-await from dependencies and updat…
Jan 12, 2026
6e3e768
fix: update login button text to use consistent capitalization and re…
Jan 12, 2026
e5219b9
docs: clean up README by removing outdated comments and updating comp…
Jan 13, 2026
d2bd1c3
docs: add Nuxt Module to Docosorus
Jan 13, 2026
e3b04e5
chore: update pnpm-lock.yaml to reflect dependency version upgrades a…
Jan 13, 2026
5883058
refactor: remove the need to add diagnostics schema manually
Jan 15, 2026
2bda6eb
docs: update README to reflect removal of top-level await plugin and …
Jan 15, 2026
49060a0
refactor: standardize table names to lowercase in SQL queries and upd…
Jan 15, 2026
510a96f
feat: added multitab support
Jan 15, 2026
6363f30
chore: add reset:repo script to clean node_modules and pnpm lock file…
Jan 20, 2026
35490f8
chore: update author name in package.json from JOURNEYAPPS to POWERSYNC
Jan 20, 2026
30062cc
Merge branch 'main' into nuxt
Jan 20, 2026
dd7181c
chore: lay the ground for demo Isolation
Jan 20, 2026
754581d
fix: removed vue deps from demo project to allow pnpm to resolve a si…
Jan 20, 2026
fb28c97
feat: made Kysely integration in Nuxt module optional
Jan 21, 2026
4d5ff6c
feat: added local development guide with supabase
Jan 21, 2026
a65a509
refactor: clean up and reorganize Vue components in the todolist demo…
Jan 21, 2026
18b4319
refactor: replace watch with watchEffect for user navigation in confi…
Jan 21, 2026
9c2fe9e
feat: add LoadingSpinner component and integrate it into powersync-in…
Jan 21, 2026
4d57259
fix: fixed flickering cause by icon size change when status change
Jan 21, 2026
30702fa
feat: define BucketRow and TableRow types for improved type safety in…
Jan 22, 2026
939eb89
test: implement unit tests for nuxt package
Jan 27, 2026
02a3a1a
fix: fixed nuxt package docs generation
Jan 27, 2026
f304989
fix: typed the return type of usePowerSyncInspectorDiagnostics compos…
Jan 27, 2026
8e3e6f0
build: add prebuild:prod script to streamline production build proces…
Jan 28, 2026
597666a
chore: Isolated nuxt-supabase-todolist demo and remove it from workspace
Jan 28, 2026
ee63d71
Merge branch 'main' into nuxt
Jan 28, 2026
68bb624
chore: update package dependencies versions in nuxt demo
Jan 28, 2026
b1d2fe1
fix: fixed type issues in docs build and added missing dependencies
Jan 28, 2026
5931a86
chore: update nuxt package version to 0.0.0-dev-20260128023420
Jan 28, 2026
fccf045
chore: add missing deps for nuxt packages tests
Jan 28, 2026
e195ba3
docs: updated docs to reflect latest changes and update nuxt-supabase…
Jan 28, 2026
9444525
feat: initial release of PowerSync Nuxt module with Devtools integrat…
Jan 28, 2026
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
5 changes: 5 additions & 0 deletions .changeset/gentle-poems-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@powersync/nuxt': minor
---

Initial release of the PowerSync Nuxt module. Provides Nuxt Devtools integration, built-in diagnostics and data inspection, and composables. Supports Nuxt 4.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
node_modules
.env
lib
!tools/diagnostics-app/src/lib/
dist
.nuxt
.output
*.tsbuildinfo
.vscode
.DS_STORE
Expand All @@ -17,3 +20,6 @@ demos/**/pnpm-lock.yaml

# Useful for local development
demos/**/.pnpmfile.cjs
demos/**/.branches
demos/**/.temp

15 changes: 15 additions & 0 deletions demos/nuxt-supabase-todolist/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Self-hosted Environment Configuration
# Copy this template: `cp .env.template .env`
# Edit .env and enter your Supabase and PowerSync project details.

NUXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NUXT_PUBLIC_SUPABASE_ANON_KEY=<replace-with-your-anon-key-or-copy-publishable-key-from-supabase-start>
# PowerSync Configuration
NUXT_PUBLIC_POWERSYNC_URL=http://localhost:6000

# Self-hosted PowerSync Configuration
PS_POSTGRESQL_URI=postgresql://postgres:postgres@supabase_db_nuxt-supabase-todolist:5432/postgres
# PS_SUPABASE_JWT_SECRET=super-secret-jwt-token-with-at-least-32-characters-long # Uncomment this if you want to use legacy Supabase JWT secret for auth
PS_JWKS_URI=http://kong:8000/auth/v1/.well-known/jwks.json
PS_API_TOKEN=super-secret
PS_PORT=6000
1 change: 1 addition & 0 deletions demos/nuxt-supabase-todolist/.nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports.autoImport=true
136 changes: 136 additions & 0 deletions demos/nuxt-supabase-todolist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# PowerSync + Supabase Nuxt Demo: Todo List

This is a demo application showcasing PowerSync integration with Nuxt 4 and Supabase. It demonstrates real-time data synchronization for a simple todo list application using PowerSync's official Nuxt module.

## Setup Instructions

Note that this setup guide has minor deviations from the [Supabase + PowerSync integration guide](https://docs.powersync.com/integration-guides/supabase-+-powersync). Below we refer to sections in this guide where relevant.

### 1. Install dependencies

In the repo root directory, use [pnpm](https://pnpm.io/installation) to install dependencies:

```bash
pnpm install
pnpm build:packages
```

### Quick Start: Local Development

This demo can be started with local PowerSync and Supabase services.

1. Install the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started)

2. Copy the environment template:
```bash
cp .env.template .env
```

3. Start Supabase:
```bash
supabase start
```

4. Copy the values from the `supabase start` output into `.env`. Local Supabase uses JWKS for auth, so this demo configures PowerSync with `jwks_uri` and `audience: authenticated`:
- `NUXT_PUBLIC_SUPABASE_ANON_KEY`: Use the **Publishable** key value
- `PS_JWKS_URI`: Use `http://kong:8000/auth/v1/.well-known/jwks.json` when PowerSync runs in Docker on the Supabase network (default in step 5). This points PowerSync at local Supabase's JWKS so it can verify tokens. If Kong is not reachable from the container (e.g. custom network), try `http://host.docker.internal:54321/auth/v1/.well-known/jwks.json` on Docker Desktop for Mac/Windows.

5. Start PowerSync:
```bash
docker run \
-p 6060:6060 \
-e POWERSYNC_CONFIG_B64=$(base64 -i ./powersync.yaml) \
-e POWERSYNC_SYNC_RULES_B64=$(base64 -i ./sync-rules.yaml) \
--env-file ./.env \
--network supabase_network_nuxt-supabase-todolist \
--name powersync-nuxt journeyapps/powersync-service:latest
```

6. Run the demo:
```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) to use the app.

### 2. Create project on Supabase and set up Postgres

This demo app uses Supabase as its Postgres database and backend:

1. [Create a new project on the Supabase dashboard](https://supabase.com/dashboard/projects).
2. Go to the Supabase SQL Editor for your new project and execute the SQL statements in [`db/seed.sql`](db/seed.sql) to create the database schema, PowerSync replication role, and publication needed for PowerSync.

**Note:** Before executing the SQL, make sure to update the `powersync_role` password in `db/seed.sql` (currently set to `'postgres_12345'`) to a secure password of your choice.

**Important:** When connecting PowerSync to your Supabase database, you'll use the `powersync_role` credentials instead of the default Supabase connection string. This role has the necessary replication privileges and bypasses Row Level Security (RLS).

### 3. Auth setup

This app uses Supabase's email/password authentication.

1. Go to "Authentication" -> "Providers" in your Supabase dashboard
2. Ensure "Email" provider is enabled
3. You can disable email confirmation for development by going to "Authentication" -> "Email Auth" and disabling "Confirm email"

You'll need to create a user account when you first access the application.

### 4. Set up PowerSync

You can use either PowerSync Cloud or self-host PowerSync:

- **PowerSync Cloud**: [Create a new project on the PowerSync dashboard](https://dashboard.powersync.com) and connect it to your Supabase database using the `powersync_role` credentials created in step 2.
- **Self-hosting**: Follow the [self-hosting guide](https://docs.powersync.com/self-hosting/getting-started) to deploy your own PowerSync instance.

The sync rules for this demo are provided in [`sync-rules.yaml`](sync-rules.yaml) in this directory.

### 5. Set up local environment variables

Create a `.env` file in this directory with the following variables:

```bash
NUXT_PUBLIC_SUPABASE_URL=your_supabase_url
NUXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
NUXT_PUBLIC_POWERSYNC_URL=your_powersync_instance_url
```

Replace the values with your actual credentials:
- Get `NUXT_PUBLIC_SUPABASE_URL` and `NUXT_PUBLIC_SUPABASE_ANON_KEY` from your Supabase project settings under "Project Settings" -> "API"
- Get `NUXT_PUBLIC_POWERSYNC_URL` from your PowerSync instance (Cloud dashboard or your self-hosted instance URL)

### 6. Run the demo app

In this directory, run the following to start the development server:

```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to try out the demo.

## Project Structure

```
├── powersync/
│ ├── AppSchema.ts # PowerSync schema definition
│ └── SuperbaseConnector.ts # Supabase connector implementation
├── plugins/
│ └── powersync.client.ts # PowerSync plugin setup
├── pages/
│ ├── index.vue # Main todo list page
│ ├── login.vue # Login page
│ └── confirm.vue # Auth confirmation page
├── components/
│ └── AppHeader.vue # Header component
├── db/
│ └── seed.sql # Database setup SQL
├── powersync.yaml # PowerSync server configuration
├── sync-rules.yaml # PowerSync sync rules
└── nuxt.config.ts # Nuxt configuration
```

## Learn More
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if this demo had a local Supabase config and quickstart for local development - which can be used to start the demo in only a few commands - like the YJS Demo has here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added all necessary files and instructions for this


- [PowerSync Documentation](https://docs.powersync.com/)
- [Supabase Documentation](https://supabase.com/docs)
- [Nuxt Documentation](https://nuxt.com/)

20 changes: 20 additions & 0 deletions demos/nuxt-supabase-todolist/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default defineAppConfig({
ui: {
colors: {
primary: 'indigo',
neutral: 'stone',
},
input: {
variants: {
variant: {
subtle: 'ring-default bg-elevated/50',
},
},
},
header: {
slots: {
root: 'border-none',
},
},
},
})
58 changes: 58 additions & 0 deletions demos/nuxt-supabase-todolist/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest that we keep a consistent orders for templates/script blocks across all our components in this demo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I have made things more consistent now.

<UApp>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</UApp>
</template>

<script setup lang="ts">
useHead({
meta: [{ name: 'viewport', content: 'width=device-width, initial-scale=1' }],
link: [{ rel: 'icon', href: '/favicon.ico' }],
htmlAttrs: {
lang: 'en',
},
})

const title = 'PowerSync Playground'
const description
= 'Demo of a simple todo list app using PowerSync and Supabase.'

useSeoMeta({
title,
ogTitle: title,
description,
ogDescription: description,
})

const appIsReady = ref(false)

provide('appIsReady', readonly(appIsReady))

const powerSync = usePowerSync()
const syncStatus = usePowerSyncStatus()

const user = useSupabaseUser()
const { logger: powerSyncLogger } = useDiagnosticsLogger()

watch(user, () => {
if (user) {
if (syncStatus.value.hasSynced) {
powerSyncLogger.log('User is logged in and has synced...', { user: user, syncStatus: syncStatus.value })
appIsReady.value = true
}
else {
powerSyncLogger.log('User is logged waiting for first sync...', { user: user, syncStatus: syncStatus.value })
powerSync.value.waitForFirstSync().then(() => {
appIsReady.value = true
})
}
}
else {
powerSyncLogger.log('User is not logged in disconnecting...', { user: user, syncStatus: syncStatus.value })
powerSync.value.disconnect()
appIsReady.value = true
}
}, { immediate: true })
</script>
8 changes: 8 additions & 0 deletions demos/nuxt-supabase-todolist/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import "tailwindcss";
@import "@nuxt/ui";

:root {
--ui-header-height: 40px;

--ui-container: 100%;
}
14 changes: 14 additions & 0 deletions demos/nuxt-supabase-todolist/assets/img/powersync-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions demos/nuxt-supabase-todolist/components/AppHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<UHeader :toggle="false">
<template #left>
<UButton variant="link" @click="navigateTo('/')">
<img src="~/assets/img/powersync-icon.svg" alt="Powersync" class="size-10 inline-flex">
</UButton>
</template>

<template #right>
<UColorModeButton variant="link" />

<UButton v-if="user" variant="link" class="cursor-pointer" color="neutral" @click="logout">
Logout
</UButton>
</template>
</UHeader>
</template>

<script setup lang="ts">
const client = useSupabaseClient()
const user = useSupabaseUser()
const powerSync = usePowerSync()

const logout = async () => {
await powerSync.value.disconnectAndClear()

await client.auth.signOut()
navigateTo('/login')
}
</script>
28 changes: 28 additions & 0 deletions demos/nuxt-supabase-todolist/db/seed.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-- Past this into your Superbase SQL Editor

-- TODO change this if changing the DB connection name
-- connect postgres;
-- Create tables

CREATE TABLE IF NOT EXISTS public.tasks(
id uuid NOT NULL DEFAULT gen_random_uuid(),
created_at timestamp with time zone NOT NULL DEFAULT now(),
completed_at timestamp with time zone NULL,
description text NOT NULL,
completed boolean NOT NULL DEFAULT FALSE,
user_id uuid NOT NULL,
CONSTRAINT tasks_pkey PRIMARY KEY (id)
);

-- Create a role/user with replication privileges for PowerSync
CREATE ROLE powersync_role WITH REPLICATION BYPASSRLS LOGIN PASSWORD 'postgres_12345';
-- Set up permissions for the newly created role
-- Read-only (SELECT) access is required
GRANT SELECT ON ALL TABLES IN SCHEMA public TO powersync_role;

-- Optionally, grant SELECT on all future tables (to cater for schema additions)
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO powersync_role;


-- Create publication for PowerSync tables
CREATE PUBLICATION powersync FOR ALL TABLES;
9 changes: 9 additions & 0 deletions demos/nuxt-supabase-todolist/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs'

export default withNuxt({
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'nuxt/nuxt-config-keys-order': 'off',
},
})
9 changes: 9 additions & 0 deletions demos/nuxt-supabase-todolist/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<div>
<AppHeader />

<UMain>
<slot />
</UMain>
</div>
</template>
Loading