Demo app in Vue (Vue3, file-based routing, SupaBase, CRUD, Pinia, Tailwind,...)
Work in progress...
TBC – TO BE CONTINUED: See TODO below for known bugs and ideas for improvement and addiitional features.
npm create vue@latest
cd vue-app
npm install
npm run devChecking for module updates.
npm install -g npm-check-updates
ncu -u
npm installFile-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-jsSupabase local development, e.g. for DB migrations.
npm install supabase --save-devInitialize 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 --linkedCreating database types Generating Typescript types
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > database.types.tsSet 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.jsIf you want to change the projects data for instance (e.g. add descriptions to projects):
- add a DB column
descriptionto theprojectstable invue-app/supabase/migrations/20250415144650_projects-schema.sql - add the
descriptionfield 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:typesDB 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-devnpm run db:migrate:new profiles-schemaUsed 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.htmlAdding an input component:
npx shadcn-vue@latest add inputUsing 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-vueThe 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-iconUnplugin Auto Imports is used to automatically import commonly used functions and components in Vue.js applications.
npm install -D unplugin-auto-importCurrently 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:resetThis 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
- Add more features based on VueUse (Collection of Vue Composition Utilities), e.g. for login password validation
- Project title change also changes slug in the URL
- Add table sorting, reordering, and filtering capabilities
- Add pagination to the project list
- Add a project changed date field and display it (optionally) in the project list
- Add project description in the projects list (truncated with ellipsis)
- Add ellipsis to project title in the project list
- Add data export option? (later import/restore even?)
- Vitest/Jest
- Storybook
- E2E tests with Playwright
- Add search (against backend in case of large data set)
- Fix: Readonly status icons should not have links. Icons should have alt text.
- Use status icons in the tasks list
- Add projects features to tasks list too (e.g. collaborators – ensure multi-collaborator works too; add uuid users to database)
- Refactor to better software architecture, other state management, or such?
- User data should be consistent uuids (not ["1", "2", "3"]), compare tasks and projects listing. Make sure Supabase setup scripts create proper data for fresh projects.
- Add proper/ more extensive examples for Builder.io integration
- Add proper/ more extensive examples for Storyblok integration
https://www.storyblok.com/technologies#vue
npm i @storyblok/vue