---
title: 'Build a User Management App with Ionic Vue'
description: 'Learn how to use Supabase in your Ionic Vue App.'
---
<$Partial path="quickstart_intro.mdx" />

If you get stuck while working through this guide, refer to the [full example on GitHub](https://github.com/mhartington/supabase-ionic-vue).
<$Partial path="project_setup.mdx" variables={{ "framework": "vuejs", "tab": "frameworks" }} />
## Building the app
Let's start building the Vue app from scratch.
### Initialize an Ionic Vue app
We can use the [Ionic CLI](https://ionicframework.com/docs/cli) to initialize an app called `supabase-ionic-vue`:
```bash
npm install -g @ionic/cli
ionic start supabase-ionic-vue blank --type vue
cd supabase-ionic-vue
```
Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js)
```bash
npm install @supabase/supabase-js
```
And finally we want to save the environment variables in a `.env`.
All we need are the API URL and the key that you copied [earlier](#get-api-details).
<$CodeTabs>
```bash name=.env
VITE_SUPABASE_URL=YOUR_SUPABASE_URL
VITE_SUPABASE_PUBLISHABLE_KEY=YOUR_SUPABASE_PUBLISHABLE_KEY
```
$CodeTabs>
Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database.
<$CodeTabs>
```js name=src/supabase.ts
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL as string;
const supabasePublishableKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY as string;
export const supabase = createClient(supabaseUrl, supabasePublishableKey);
```
$CodeTabs>
### Set up a login route
Let's set up a Vue component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords.
<$CodeTabs>
```html name=/src/views/Login.vue
Login
Supabase + Ionic Vue
Sign in via magic link with your email below
{{ email }}
```
$CodeTabs>
### Account page
After a user is signed in we can allow them to edit their profile details and manage their account.
Let's create a new component for that called `Account.vue`.
<$CodeTabs>
```html name=src/views/Account.vue
Account
Log Out
```
$CodeTabs>
### Launch!
Now that we have all the components in place, let's update `App.vue` and our routes:
<$CodeTabs>
```ts name=src/router.index.ts
import { createRouter, createWebHistory } from '@ionic/vue-router'
import { RouteRecordRaw } from 'vue-router'
import LoginPage from '../views/Login.vue'
import AccountPage from '../views/Account.vue'
const routes: Array = [
{
path: '/',
name: 'Login',
component: LoginPage,
},
{
path: '/account',
name: 'Account',
component: AccountPage,
},
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})
export default router
```
```html name=src/App.vue
```
$CodeTabs>
Once that's done, run this in a terminal window:
```bash
ionic serve
```
And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app.

## Bonus: Profile photos
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos.
### Create an upload widget
First install two packages in order to interact with the user's camera.
```bash
npm install @ionic/pwa-elements @capacitor/camera
```
[Capacitor](https://capacitorjs.com) is a cross-platform native runtime from Ionic that enables web apps to be deployed through the app store and provides access to native device API.
Ionic PWA elements is a companion package that will polyfill certain browser APIs that provide no user interface with custom Ionic UI.
With those packages installed we can update our `main.ts` to include an additional bootstrapping call for the Ionic PWA Elements.
<$CodeTabs>
```ts name=src/main.tsx
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { IonicVue } from '@ionic/vue'
/* Core CSS required for Ionic components to work properly */
import '@ionic/vue/css/ionic.bundle.css'
/* Theme variables */
import './theme/variables.css'
import { defineCustomElements } from '@ionic/pwa-elements/loader'
defineCustomElements(window)
const app = createApp(App).use(IonicVue).use(router)
router.isReady().then(() => {
app.mount('#app')
})
```
$CodeTabs>
Then create an `AvatarComponent`.
<$CodeTabs>
```html name=src/components/Avatar.vue
```
$CodeTabs>
### Add the new widget
And then we can add the widget to the Account page:
<$CodeTabs>
```html name=src/views/Account.vue
Account
...
```
$CodeTabs>
At this stage you have a fully functional application!