Vue3とSupabaseで作るGoogleアカウント認証サイト

# はじめに

Googleアカウントのログイン機能付き簡易webサイトを、**Vue3**と**Supabase**を利用して作る方法を説明します。

Vue3で簡単なウェブアプリを作る際に、Googleアカウントでログインできるようにすれば、セキュリティも高まるし、ユーザー情報も使えて便利だなと思ったので、作り方を探しましたが、ハンズオン例が少なかった(Next.js強し…)ので、記事にしてみました。

またログインをできるだけ簡単に実装したかったので、話題の**Supabase**に入門してみました。

## こんな方にお薦めの記事です

- **Vue3**で**Supabase**のGoogleアカウントの認証を試してみたい方
- **Vue3　Composition API**で**Supabase**の連携について知りたい方
- アプリのフロントエンドで簡単な認証ページがほしい方

## 構築に必要なもの

- node.js
- npm
- Googleアカウント
- Google Cloud Platformアカウント
- Supabaseアカウント

前提として、Node.jsのインストールや、GCPとSupabaseのアカウントの作成が必要です。

## 構築内容について

### Vue3

- **Vue３**は**Composition API**を利用
- **Typescript**不使用
- ルーティング管理の**vue router**
- 状態管理ライブラリの**Pinia**

### Supabase

- **Supabase Auth**を利用
- 認証のみなので、今回はDatabase利用なし

### Google Cloud Platform

- プロジェクトの作成
- 認証情報の作成

# 構築手順

それではやっていきたいと思います。最初にSupabaseとGoogle Cloud Platformの連携から行います。

## supabaseでプロジェクト作成

[Supabase](https://supabase.com/ "Supabase")を開いて、プロジェクトを作成します。

![Supabase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/c783a4a0-c61f-8178-5c96-ceb2fd2ede93.png)

プロジェクト名、Database Passwordを決めて入力します。作成したプロジェクトはメニューが沢山ありますが、今回は基本的なAPI設定とAuthのわかりやすい機能のみを使いたいと思います。

## GCP OAuth同意画面設定

作成したSupabaseのダッシュボード画面とは別ウィンドウで、[Google Cloud Platformのコンソール画面](https://console.cloud.google.com/home/dashboard "Google Cloud Platformのコンソール画面")を開きます。

新しいプロジェクトを作成します。

![新しいプロジェクト_–_ダッシュボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/a1ce951b-0c64-533f-a0c3-41d863b6d4aa.png)

プロジェクトに移動し、[OAuth同意画面](https://console.cloud.google.com/apis/credentials/consent "Google Cloud Platform　OAuth同意画面")を開き設定をします。

![gcp_menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/d942d7c8-e585-197b-edb5-f41dd92f7d39.png)

**UserType**には、Google Workspaceのような組織アカウントを利用したい場合は`Internal`を、すべてのGoogleアカウントからのログインには`External`を選択します。今回はExternalで進めます。

![Cursor_と_API_とサービス_–_mt-supabase-auth-de…_–_Google_Cloud_コンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/7b3c97f5-9510-e15c-fcfd-01b0beb40ad9.png)

### アプリ情報の設定

GCPが作成してくれる同意画面の情報を入力します。`アプリ名`、`ユーザーサポートメール`、`デベロッパーの連絡先情報`は必須項目になっていますので、それぞれ入力してください。

![API_とサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/5281561d-b700-b13b-2358-a6fb7dcc0530.png)

Googleアカウントから取得したい項目の許可を設定するため、以下のスコープを追加します。

\- .../auth/userinfo.email
\- ...auth/userinfo.profile
\- openid

![スコープ更新.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/60e1acec-926c-a403-0f8f-cd5d8d1cf5eb.png)

OAuth同意画面を作成した直後はステータスが`Testing`になっており、テストユーザーのみがアクセスできるようになっています。本来であればテストユーザーを追加する流れなのだと思いますが、supabaseの場合、テストユーザーを設定せずともログイン出来ているので、テストユーザーの設定はそのまま次に進めます。（本番利用時は公開が必要）

![テストユーザー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/a232cd6e-fcf0-e724-bf41-6ed928b35937.png)

サマリーを確認して完了させます。

![サマリー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/9b04216e-b116-d5b0-8627-b78a7e286a33.png)

## GCP 認証情報設定

[GCPの認証情報](https://console.cloud.google.com/apis/credentials)を開きます。

`＋認証情報を作成`からOAuthクライアントIDを選び、アプリケーションの種類に`ウェブアプリケーション`を選択し、任意の名前を入力します。

![認証情報_–_API_とサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/01cc73bf-a249-2434-05bc-018d4bb7e53f.png)

![Create_OAuth_client_ID_–_API_とサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/d340d2c9-985c-85f8-6613-d197787aab39.png)

ブラウザの別の画面でSupabaseを開いて、メニューから[Authentication>Privider](https://supabase.com/dashboard/project/_/auth/providers)を選択します。一覧にGoogleがあるので、メニューを開いて、Callback URL(for OAuth)にあるURLをコピーします。

![Cursor_と_Authentication___Supabase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/308fbfd9-db2b-5f7c-f4d1-f592df801ed3.png)

GCP側の「承認済みのリダイレクト URI」にコピーしたURLを貼り付け、作成ボタンを押します。

![redirect_url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/197c28ac-9de9-0468-0302-f630b5fb0e86.png)


作成されたOAuthクライアントからクライアントIDとクライアントシークレットをコピーしておきます。

![clientcode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/4edcde07-a77d-0386-3e61-3f06edd5e477.png)


## SupabaseへクライアントIDを登録

SupabaseのAuthentication画面でコピーしたクライアントIDとクライアントシークレットをGoogleの認証設定に貼り付け、`Enable Sign in with Google`をONにして保存します。

![Authentication___Supabase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/8cf9106a-4f3f-8db1-6a43-c4545d99252e.png)

Googleの項目が`Enabled`になっていれば設定完了です。


![Cursor_と_Authentication___Supabase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/29b8146f-87c6-5503-4bb4-1468b201fce2.png)


## Vueアプリを構築

Vueアプリを構築していきます。構築にあたってはアールエフェクト様の記事を**参考**にさせていただきました。


https://reffect.co.jp/vue/supabase-vue3#google_vignette

Vueはこのサイトでお勉強させていただきました。初心者の私にもわかりやすく、初学の方にお薦めです。

### プロジェクトの作成

npmを使って、ローカル環境にプロジェクトを作成します。ターミナルで下記のコマンドを好きなローカルフォルダで実行します。

```
npm init vue@latest
```

対話式のインストールが始まります。


```bash
❯ npm init vue@latest
Need to install the following packages:
create-vue@3.10.4
Ok to proceed? (y) y

Vue.js - The Progressive JavaScript Framework

✔ Project name: … vue-googlelogin-app
✔ Add TypeScript? … No
✔ Add JSX Support? … No
✔ Add Vue Router for Single Page Application development? … Yes
✔ Add Pinia for state management? … Yes
✔ Add Vitest for Unit Testing? … No
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No
✔ Add Vue DevTools 7 extension for debugging? (experimental) … No

Scaffolding project in /Users/**/***/vue/dev/vue-googlelogin-app...

Done. Now run:

  cd vue-googlelogin-app
  npm install
  npm run dev
```

いくつか項目がありますが、Vueルーターを追加する、`Add Vue Router for Single Page Application development?`と、状態管理のPiniaを使うために`Add Pinia for state management?`を`Yes`で進めました。

## VueとSupabaseの接続

作成されたプロジェクトフォルタに移行して初期インストールを行います。

```
cd vue-googlelogin-app
npm install
```

次にSupabaseのライブラリを追加します。
```
npm install @supabase/supabase-js
```

インストール後、プロジェクトフォルダの直下（package.jsonなどと同じ階層）に.envファイルを作成します。
作成したファイルにSupabaseのプロジェクト画面にある、Project APIから`Project URL`と`API Key`をコピーして、`.env`ファイルに保存します。


![api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/2abc022f-b0a3-4745-bd16-153ce41905db.png)


```.env
VITE_SUPABASE_URL=YOUR_SUPABASE_URL　# プロジェクトURLをここに
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY　# API　Keyをここに
```

次にSupabaseのクライアントを読み込むためにsrcフォルダへ`supabase.js`ファイルを作成します。

```src/supabase.js
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)
```

## Piniaにauth.jsを作成

まずは状態管理ライブラリのPiniaのファイルを作成します。PiniaはVueのインストール時に同時にインストールしました。`ｓｒｃ>stores`にあるデフォルト入っている`counter.js`を**削除**して、代わりに`auth.js`を作成します。

```src/stores/auth.js
import { defineStore } from 'pinia';
export const useAuthStore = defineStore({
    id: 'auth',
    state: () => ({
        user: null,
    }),
    getters: {
        isLoggedIn: (state) => state.user,
    },
    actions: {
        setUser(user) {
            this.user = user;
        },
        clearUser() {
            this.user = null;
        },
    },
});
```

ユーザーのログイン状態を保管するために、`state`無いにuserを初期値`null`で設定しました。

`getters`には`isLoggin`が定義されていて、userのログイン状態を返すことで、現在のログイン状態を判断できるようになっています。
`action`にはGoogleアカウントでサインインした場合に、userに値をセットする`setUser`とサインアウトした場合にuserの値を削除する`clearUser`を定義しています。

これらの設定を`useAuthStore`としてexportして、他のvueファイルよりimportして読み込みます。

## App.vueを修正

デフォルトで作成されるApp.vueを修正します。一度、中身をすべて削除し、下記のコードに書き換えます。

```src/App.vue
<script setup>
import { supabase } from './supabase';
import { useAuthStore } from './stores/auth';
const auth = useAuthStore();

async function fetchUser() {
  const { data, error } = await supabase.auth.getSession();
  if (error) {
    console.error('Error fetching session:', error);
    auth.clearUser();
  } else {
    auth.setUser(data.session?.user ?? null);
  }
}

fetchUser();

supabase.auth.onAuthStateChange(async (event, session) => {
  if (event === 'SIGNED_IN' && session) {
    auth.setUser(session.user);
  } else if (event === 'SIGNED_OUT') {
    auth.clearUser();
  }
});
</script>

<template>
  <router-view></router-view>
</template>
```



scriptタグ内でSupabaseのjsファイルを読み込み、piniaに設定した`useAuthStore`をimportしています。使いやすいように`auth`へ`useAuthStore()`を格納しています。

fetchUser()で状態を、onAuthStateChangeでイベントの発生をそれぞれ監視しています。

### fetchUser()

`fetchUser()`はsupabaseのセッション状態を取得する関数`supabase.auth.getSession()`を利用し、ブラウザのローカルストレージに保存されたsupabaseのセッション情報を取得します。ログイン中の場合は`auth.setUser()`を利用して、Piniaのuser情報に取得したセッション情報を格納します（もしdataが無かったらnullを代入）。またセッションがなければ`auth.clearUser()`でユーザー情報を削除します。

### supabase.auth.onAuthStateChange

`supabase.auth.onAuthStateChange`はサインインとサインアウトのイベントを監視し、`SIGNED_IN`イベントが発生した際はsession.userの情報をpiniaのuserへ格納します。`SIGNED_OUT`はuser情報をclearUserで削除します。


### templateタグ

App.vueファイルの`template`タグはVue Routerを利用しているので、ルーティングで設定したVueのページコンポーネントを読み込む内容です。

ここまでで一度`npm run dev`で動作確認します。

```
npm run dev
```

```
  VITE v5.3.1  ready in 149 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
```

表示されたURLにブラウザでアクセスします。

![Cursor_と_Vite_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/ae5b81d5-74b8-f8d9-4ba0-01bce1008e77.png)

現在の`router/index.js`で設定されている`/views/HomeView.vue`の内容が表示されています。エラーが出ていなければ、ここまでの設定はOKです。

## ルーティングの設定

`src/view`フォルダに以下の３つのファイルを追加します。

- SignIn.vue
- AuthCallback.vue
- DashBoard.vue

ファイルの中身は、あとで変更するので、同じ内容でも構いません。

```
<template>
  <h1>Title</h1>
</template>
```

ファイルが作成できたら、`src/router/index.js`ファイルを編集し、追加したファイルのルーティングを追加します。

```src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/signin',
      name: 'signin',
      component: () => import('../views/SignIn.vue'),　　// サインイン画面
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: () => import('../views/DashBoard.vue'), // ログイン後のダッシュボード
    },
    {
      path: '/auth/callback',
      name: 'authCallback',
      component: () => import('../views/AuthCallback.vue'), // 認証後の処理を行うビュー
    },
  ]
})

export default router
```

`http://localhost:5173/signin`などのURLを開いてみて、`Title`と表示されれば、ルーティングが正常に稼働しています。

![Vite_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/d281d420-0277-4d98-e0dd-9caa41d5def4.png)


## HomeView.vueを修正

ルーティングが出来たので、ルートディレクトリで表示されるHomeView.vueを修正します。

状態管理ライブラリPiniaで定義したuseAuthStoreにある、gettersのisLoggedInを使って、ルートディレクトリ`/`へアクセスしたときに表示されるリンクを切り替えています。


```/src/view/HomeView.vue
<script setup>
import { useAuthStore } from '../stores/auth';

const auth = useAuthStore();
</script>

<template>
  <ul>
    <li v-if="auth.isLoggedIn">
      <router-link to="/dashboard">Dashboard</router-link>
    </li>
    <li v-if="!auth.isLoggedIn">
      <router-link to="/signin">SignIn</router-link>
    </li>
  </ul>
  <h1>Supabase + Vue3 + Pinia</h1>
</template>

<style scoped>
</style>
```

サインインしていない状態では`user`の値には`null`となっているので、`isLoggedIn`はfalseとなり、`SignIn`のリンクのみが表示されています。

![Vite_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/9f0d7485-06cf-08c8-fdf5-db0cd0e74a31.png)

## サインイン機能の実装

さきほど/src/viewへ追加したSignIn.vueを下記に置き換えます。

### SignIn.vue


```/src/view/SignIn.vue
<script setup>
import { ref } from 'vue';
import { supabase } from '../supabase';
import { useRouter } from 'vue-router';

const router = useRouter();
const error = ref(null);

const signInWithGoogle = async () => {
    const { error } = await supabase.auth.signInWithOAuth({
        provider: 'google',
        options: {
            redirectTo: `${window.location.origin}/auth/callback`,
            queryParams: {
                prompt: 'select_account'
            }
        }
    });

    if (error) {
        console.error('Login failed:', error.message);
    }
};
</script>

<template>
    <div>
        <h1>Sign In</h1>
        <button @click="signInWithGoogle">Sign in with Google</button>
        <p v-if="error">{{ error }}</p>
    </div>
</template>
```

Googleアカウントのサインインボタンを表示する画面になります。

`signInWithGoogle`内で`supabase.auth.signInWithOAuth()`を利用して、OAuth認証を行います。認証プロバイダーに`google`を指定し、optionsパラメータ内で認証を行った後の遷移先パスを`redirectTo`で設定しています。

queryParamsに`prompt: 'select_account'`を指定していますが、これはGoogleアカウントのログイン時に毎回ユーザーを選択する画面を表示させるためです。この設定が無いと、毎回同じユーザーでログインするようになります。設定した場合と設定しない場合はコメントアウトなどで試していただけると動作の違いがわかると思います。

### AuthCallBack.vue

つぎにログイン処理後の状態に応じて、遷移先の画面を振り分ける`AuthCallBack.vue`を変更します。

```/src/view/AuthCallBack.vue
<script setup>
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { supabase } from '../supabase';

const router = useRouter();

onMounted(async () => {
    const { data: { session }, error } = await supabase.auth.getSession();

    if (error) {
        console.error('認証エラー:', error.message);
        router.push({ name: 'signin' });
    } else if (session) {
        router.push({ name: 'dashboard' });
    } else {
        router.push({ name: 'home' });
    }
});
</script>

<template>
    <div>
        <h1>認証を処理しています...</h1>
    </div>
</template>
```

`supabase.auth.getSession()`でログイン状態を確認して、Vueルーターで画面をリダイレクトさせています。認証に時間がかかる場合のローディング画面のようなものです。ネットワークの状態などによってはほぼ表示されなかったりします。

この時点でGoogleアカウントを使ったログインができるようになります。では実際にログイン処理を行ってみます。

ホーム画面の`SignIn`を押して、`SignIn.vue`を表示させます。


![Vite_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/bc1316d8-04bf-3d67-ce91-39be33986721.png)

`Sign in with Google`ボタンを押します。


![ログイン_-_Google_アカウント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/a2cbf624-29a8-2697-fd91-9edc8f2ae68c.png)



Googleのアカウント選択画面が表示されましたので、アカウントをクリックします。


![ログイン_-_Google_アカウント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/95243ac8-413c-67b5-951b-2ecc00c41b30.png)

Googleアカウントへの接続同意画面が表示されました。内容を確認して`次へ`を押します。


![2024_06_21_16_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/edde6389-3f86-6e0d-8095-0ce2b04a6638.png)


ログインに成功していると、URLが`Dashboard`に切り替わります。

![2024_06_21_16_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/0672d4c5-805a-881b-f474-3732f03ca487.png)

URLを直接入力して、画面を切り替えてHOMEに戻ると、SignInのリンクがなくなり、Dashboardへのリンクのみになっています。

### Dashboard.viewの修正

ログインした後のDashboardでGoogleアカウントから取得した内容を表示させます。またログアウトボタンもつ追加します。下記の内容に/src/view/DashBoard.vueを変更します。

```/src/view/DashBoard.vue
<script setup>
import { onMounted, ref, onUnmounted } from 'vue';
import { supabase } from '../supabase';
import { useRouter } from 'vue-router';

const router = useRouter();
const user = ref(null);

const handleSignOut = async () => {
    try {
        const { error } = await supabase.auth.signOut();
        if (error) throw error;
        router.push({
            name: 'home',
        });
    } catch (error) {
        alert(error.message);
    }
};

async function getUser() {
    const { data, error } = await supabase.auth.getUser();
    if (error) {
        console.error('Error fetching user:', error.message);
    } else {
        console.log(data); // デバッグ用
        user.value = data.user;
    }
}

onMounted(async () => {
    await getUser();
});


</script>

<template>
    <h1>DashBoard</h1>
    <div v-if="user">
        <button @click="handleSignOut">SignOut</button>
    </div>
    <p>Welcome to our service</p>
    <div v-if="user">
        <p><strong>Name:</strong> {{ user.user_metadata.full_name }}</p>
        <p><strong>Email:</strong> {{ user.email }}</p>
        <img v-if="user.user_metadata.avatar_url" :src="user.user_metadata.avatar_url" alt="User Avatar">
    </div>
    <div>

    </div>
</template>
```

ユーザー情報を取得するための`getUser()`とサインアウトボタン用に`handleSignOut`を定義しています。

先程のhttp://localhost:5173/dashboardを表示させます。

![2024_06_21_16_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/a71ffda7-bcea-bc69-932f-811ff94035df.png)

Googleアカウントに設定している名前、メールアドレス、アカウントの画像が表示されました。

SingOutボタンをおしてGoogleアカウントをログアウトさせます。


![Vite_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38388/8f17619e-72f3-a79d-77cc-b562d3f98fcc.png)


SignInが表示されたホーム画面へ戻りました。

ここままででGoogleアカウントのログインとログアウトはできましたが、DashboardへはURLを直接指定すれば入れてしまいますので、Vue routerへ設定を追加します。




```diff_javascript
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
+ import { useAuthStore } from '../stores/auth'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/signin',
      name: 'signin',
      component: () => import('../views/SignIn.vue'),　　// サインイン画面
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: () => import('../views/DashBoard.vue'), // ログイン後のダッシュボード
+      meta: {
+        requiresAuth: true,
+      },
    },
    {
      path: '/auth/callback',
      name: 'authCallback',
      component: () => import('../views/AuthCallback.vue'), // 認証後の処理を行うビュー
    },
  ]
});

+router.beforeEach((to) => {
+  const auth = useAuthStore();
+  if (!auth.isLoggedIn && to.meta.requiresAuth) {
+    return { name: 'signin' };
+  }
+});


export default router
```

Piniaを利用し、Vueルーターの動作前にログイン状態をチェックします。Vue Routerのナビゲーションガードという機能を利用し、ルートの定義にmetaフィールドを追加し、`requiresAuth: true`の設定があるルーティングでログイン状態ではないときに、サインイン画面にリダイレクトさせています。

https://v3.router.vuejs.org/ja/guide/advanced/navigation-guards.html#%E3%82%AF%E3%82%99%E3%83%AD%E3%83%BC%E3%83%8F%E3%82%99%E3%83%AB%E8%A7%A3%E6%B1%BA%E3%82%AB%E3%82%99%E3%83%BC%E3%83%88%E3%82%99


https://v3.router.vuejs.org/ja/guide/advanced/meta.html


これでURLを直接指定しても、ログインしていないときはDashborad画面には入れないようになりました。

最後に`npm run build`でdistフォルダーへ出力すれば完成です。

あとはDashbordへ機能を追加したり、新しくルーティングを追加していけば、Googleアカウントを利用したアプリを作れますね。




# まとめ

Vue3とSupabaseを組み合わせたGoogleアカウントでログインするサイトのデモをご紹介しました。

Supabaseは勢いがあるためにアップデートが早く、サンプルコードを試しても、すでに動かなくなっているケースも多々見られました。もし当コードも動作しないようでしたらご指摘いただけると助かります。

これからVue3とSupabaseの連携を初めたい方の一助になれば幸いです。

# 最後に

今回デザインはまったく触れていないので、殺風景なアプリとなってしまいましたが、次はVue3でtailwindを利用する方法もやってみたいと思います。
またユーザーごとで出力内容を切り替えるなどもあれば、本格的にアプリとしても用途が見えてきますので、そちらも見ていきたいなと思います。

ありがとうございました。

# 参考

https://supabase.com/docs/reference/javascript/auth-api


https://supabase.com/docs/guides/getting-started/tutorials/with-vue-3


https://reffect.co.jp/vue/supabase-vue3


https://qiita.com/kaho_eng/items/a37ff001ea9eae226183


https://supabase.com/docs/guides/auth/social-login/auth-google