Demo app in Vue (Vue3, file-based routing, SupaBase, CRUD, Pinia, Tailwind,...)
Work in progress...
TBC – TO BE CONTINUED: https://vueschool.io/lessons/getting-started-with-shadcn-ui-and-vuejs https://github.com/vueschool/vuejs-masterclass-2024-edition/branches/all?query=&page=5 https://supabase.com/dashboard/project/yuzzrmawywyywsjlnwff/editor
State 2025-06-12, continue at: https://vueschool.io/lessons/register-new-users-with-supabase-auth-and-vue-js
npm create vue@latest
cd vue-app
npm install
npm run dev
Checking for module updates.
npm install -g npm-check-updates
ncu -u
npm install
File-based routing with Unplugin Vue Router. Router configuration docs for bundler usage.
https://github.com/unplugin/unplugin-vue-components
Pinia is the state management library for Vue.js applications, replacing Vuex.
Configure Pinia for hot module replacement (HMR) in development mode.
npm install @supabase/supabase-js
Supabase local development, e.g. for DB migrations.
npm install supabase --save-dev
Initialize a local Supabase project
See tutorial for more details on how to connect.
// create a new migration in the supabase migrations directory
supabase migration new <migration-name>
Reset the database to the latest migration.
// reset the local database (if one exists) to the latest migration
supabase db reset
// reset the remote database to the latest migration
supabase db reset --linked
Creating database types Generating Typescript types
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > database.types.ts
Set up local Supabase db correspondingly to remote db with migration files.
npm run db:reset
npx supabase migration up --linked
// then update types
npm run supabase:types
// the seed data
node database/seed.js
If you want to change the projects data for instance (e.g. add descriptions to projects):
- add a DB column
description
to theprojects
table invue-app/supabase/migrations/20250415144650_projects-schema.sql
- add the
description
field invue-app/database/seed.js
- run the seed script to update the data in the database
# Reset and repopulate db
npm run db:reset
npm run db:seed
# Create new typescript types
npm run supabase:types
DB updates should then be visible in vue-app/src/database/types.ts
.
Faker.js is used for seeding the database with test data. Localization is supported.
npm install @faker-js/faker --save-dev
npm run db:migrate:new profiles-schema
Used this schema template for the profiles
schema content.
# reset the database
npm run db:reset --linked
# generate (new) typescript types
npm run supabase:types
# seed the database with initial data
npm run db:seed
```
Setting up [new Supabase authentication/user(https://supabase.com/docs/reference/javascript/auth-signup), [tutorial](https://vueschool.io/lessons/register-new-users-with-supabase-auth-and-vue-js).
## Environment variables
Convention demands a `VITE_` prefix for environment variables that you want to expose to your _client_-side code too.
Secret environment variables are in an .env file outside the project directory (see seed.js).
## ShadCN for Vue
[Install ShadCN](https://www.shadcn-vue.com/docs/installation/vite.html) with this command instead of non-functional code from [VueSchool tutorial](https://vueschool.io/lessons/getting-started-with-shadcn-ui-and-vuejs):
```bash
# npm i -D tailwindcss@^3.4.17 autoprefixer@^10.4.20
npm install tailwindcss @tailwindcss/vite
# add files according to https://www.shadcn-vue.com/docs/installation/vite.html
Adding an input component:
npx shadcn-vue@latest add input
Using Tanstack Table with the ShadCDN data table component.
npm install @tanstack/vue-table
npx shadcn-vue@latest add table
Builder.io is a headless CMS that allows you to create and manage content for your Vue.js application. It provides a visual editor for building pages and components, which can be integrated into your Vue app.
https://www.builder.io/c/docs/integrating-builder-pages
On my Mac I had to downgrade Node.js to 20.x.x to get the Builder.io SDK working.
nvm use 20
npm install @builder.io/sdk-vue
The public key is not needed to be kept secret
Now integrate Builder content into your Vue app.
Lucide icons are used in this project. See Lucide for more details. Implemented with Iconify, icons on demand for Vue or rather for future server-side rendering Iconify Icon web components. E.G. magnifying glass SVG.
npm install iconify-icon
Unplugin Auto Imports is used to automatically import commonly used functions and components in Vue.js applications.
npm install -D unplugin-auto-import
Currently disabled for the public
schema, so all users can access all data.
Hints for further development:
@workspace Looking at your workspace, the issue (now solved/worked around, issue was no data being returned while RLS was active) is likely related to Supabase Row Level Security (RLS). By default, Supabase enables RLS on all tables which prevents anonymous users from reading data, even though the data exists in the database.
The problem is that your database seed script in database/seed.js uses the SERVICE_ROLE_KEY
which bypasses RLS, but your application is using the anonymous key (VITE_SUPABASE_ANON_KEY
) which is subject to RLS restrictions.
To fix this issue, you need to add RLS policies that allow anonymous users to read data from your tables. Here's how you can do it:
- Create a new migration file:
npm run db:migrate:new enable-rls-policies
- In the new migration file, add the following SQL:
-- Enable RLS and add policies for anonymous read access
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow anonymous read access for projects"
ON projects FOR SELECT
USING (true);
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow anonymous read access for tasks"
ON tasks FOR SELECT
USING (true);
- Apply the migration:
npm run db:reset
This should allow your application to read data while still using the anonymous key. The true
condition in the policies means anyone can read the data.
For a production app, you'd want more restrictive policies, but this will work for development. You can see more details about RLS policies in the Supabase documentation.
- Lazy loading of routes, smaller initial bundle size
- Add more components from ShadCDN
- Add more pages, e.g. a settings page
- Add more CRUD operations, e.g. for tasks
- Add more tests, e.g. for the Supabase integration
- Add more documentation, e.g. for the Supabase integration