Vercel

This guide steps through using Vercel's dashboard to create a Next.js project integrated with Supabase. To further streamline the process, we will be using the Next.js starter template, which can be automatically forked to a new GitHub repo, without leaving the dashboard!

If you don’t have a Vercel account, create one here.

Step 1: Create a Supabase project#

This guide could use an existing Supabase project, but to create the todo demo from scratch, navigate to Supabase, click Sign In and authenticate with GitHub to login or register a new account.

From the Supabase dashboard, click New project and select an organization.

Note: You may need to create an organization first.

Give your project a name, password, select a region close to your potential users and click Create new project.

Create a Supabase project

Supabase will take a couple of minutes to configure the infrastructure.

Once this is finished, navigate to SQL Editor from the sidebar menu and click New query.

This will create a new SQL snippet called "New Query". Copy and paste the following and click Run.

1create table todos (
2  id bigint generated by default as identity primary key,
3  title text,
4  is_complete boolean default false,
5  created_at timestamp with time zone default timezone('utc'::text, now()) not null
6);
7
8alter table todos enable row level security;
9
10create policy "Anyone can view todos" on todos for
11    select using (true);
12
13create policy "Anyone can add new todos" on todos for
14    insert with check (true);
15
16insert into todos(title)
17values
18  ('Create Supabase project'),
19  ('Create Vercel project'),
20  ('Install Supabase integration');

This will create a new todos table, enable row level security, add policies for selecting and inserting data, and add some example rows.

Note: To simplify this example, we are allowing anyone to select and insert rows on the todos table. Usually, these actions would be locked down to only allow logged in users to perform them. Check out this video to learn more about Row Level Security and policies.

Step 2: Create Vercel project#

From your Vercel dashboard, click New Project.

Create new Vercel project

Under the Clone Template menu, click Next.js.

Clone Next.js template

In the Create Git Repository section, click GitHub, select your username under GIT SCOPE, enter a name for your project, choose whether you want your repo private or public, and click Create.

New GitHub repo settings

This will create a new GitHub repository, clone and commit the Next.js starter project, then build and deploy your new project to Vercel.

Once you have been redirected to the Congratulations screen, click Go to Dashboard.

Navigate to Settings, Integrations, then click Browse Marketplace.

Search for Supabase and click the Supabase integration.

Supabase integration

Click Add Integration. Select your account from the Vercel Scope dropdown, and click CONTINUE.

Choose scope

Choose Specific Projects and select your new Vercel project from the dropdown, and click Add Integration.

Choose project

From the Supabase popup, select your new Vercel Project and Supabase project from the dropdowns.

Supabase integration

Step 3: Clone GitHub repo#

The fastest way to get this project running locally is to clone the repo that Vercel created for us.

Navigate back to the Vercel project Overview page, and click View Git Repository.

Vercel Project Dashboard

This will open the GitHub repo. From here, click the arrow next to Code and copy the url from the dropdown.

GitHub repo url

Open a terminal window or CLI and run the following command to clone the GitHub repo.

git clone your-repo-url.git

Open the project in your code editor of choice, and update the contents of pages/index.js to the following:

1import styles from '../styles/Home.module.css'
2
3export default function Home() {
4  return <div className={styles.container}>working</div>
5}

Run a local development server.

npm run dev

Navigate to http://localhost:3000 to confirm the project is "working".

Step 4: Pull environment variables from Vercel#

First, we need to login to Vercel using their CLI tool.

npx vercel login

This will ask if we are happy to install vercel. Type y and hit Enter.

We will then need to authenticate Vercel by selecting Continue with GitHub.

This will open a browser window where you need to authenticate with your GitHub account.

Next, we need to link our Vercel project.

npx vercel link

Step through the prompts to link the Vercel project.

Link project from Vercel

Copy the environment variables from our Vercel project.

npx vercel env pull

This will create a .env file containing our Supabase environment variables. Rename this file to .env.local to automatically ignore it from git.

Step 5: Install Supabase.js#

Install the supabase-js library.

npm i @supabase/supabase-js

Create a new file called /utils/supabase.js and add the following.

1import { createClient } from '@supabase/supabase-js'
2
3export default createClient(
4  process.env.NEXT_PUBLIC_SUPABASE_URL,
5  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
6)

Create a new file called /components/NewTodo.js and add the following.

1import { useState } from 'react'
2import supabase from '../utils/supabase'
3
4export default ({ reload }) => {
5  const [title, setTitle] = useState('')
6
7  const addTodo = async (e) => {
8    e.preventDefault()
9    await supabase.from('todos').insert({ title })
10    reload()
11    setTitle('')
12  }
13
14  return (
15    <form onSubmit={addTodo}>
16      <input value={title} onChange={(e) => setTitle(e.target.value)} />
17    </form>
18  )
19}

This component will be responsible for writing a new todo to Supabase.

Let's import our new component in pages/index.js and display a list of todos.

1import { useState, useEffect } from 'react'
2import styles from '../styles/Home.module.css'
3import supabase from '../utils/supabase'
4import NewTodo from '../components/NewTodo'
5
6export default function Home() {
7  const [todos, setTodos] = useState([])
8
9  const fetchTodos = async () => {
10    const { data } = await supabase.from('todos').select('*')
11    setTodos(data)
12  }
13
14  useEffect(() => {
15    fetchTodos()
16  }, [])
17
18  return (
19    <div className={styles.container}>
20      <NewTodo reload={fetchTodos} />
21      {todos.map((todo) => (
22        <p key={todo.id}>{todo.title}</p>
23      ))}
24    </div>
25  )
26}

Resources#