Build a Custom Client Portal on Airtable Using Sequin with Next.js
In this tutorial, you’ll see how to build a scalable, secure, and flexible client portal on Airtable using Sequin, Stytch, and Next.js. You’ll set up a custom application that allows your clients to log in securely and access only the data you want them to access. Finally, you’ll see how to make this application interactive so that your clients can sign off on projects directly from the portal.
Setting Up the Airtable Base
This demo project will start with the Airtable Project Tracker template. Copy this template to your Airtable account and open up the base.

Connecting Sequin to Airtable
While you could build a client portal that queries the Airtable API directly, this has some major drawbacks, including the following:- Airtable’s API limits you to just five requests per second, so it won’t scale well.
- Querying related records using the Airtable API is cumbersome and often involves multiple API calls. This can significantly reduce your app’s performance, especially when coupled with the API limit mentioned above.
- Finding, sorting and filtering via Airtable’s API isn’t easy.


Creating a New Next.js Application
Next.js is a React-based web development framework designed to run seamlessly on Vercel. While you could set up a new React application with a backend, Next.js makes the setup and configuration process much simpler, so it’s a great starting point for building simple frontend applications like this one. Assuming you’ve got a recent version of Node.js installed (version 10+ is recommended), usenpx to create a new application from your terminal:
project-tracker in this example), and the required base packages will be installed.

Setting Up Stytch for Authentication
To allow clients secure access to your portal, you need a way to authenticate them via their email address. While you could build this feature yourself, you can also use a third-party authentication provider such as Stytch to set this up with very little custom code. Setting up Stytch is pretty straightforward, but there’s a tutorial for setting up Stytch authentication on their blog if you’d like to see how it works. This tutorial makes use of Stytch’s Email Magic Links product. First, sign up for Stytch and get your project ID, secret, and public token from the Dashboard. Next, from your terminal, you need to install Stytch and a few other required dependencies. In this demo application, Stytch is being coupled with the next-iron-session utility to help with managing user sessions and data..env.local file in the root directory of your project. This will allow you to securely store your environment variables without checking them into version control.
... with the corresponding environment variable from each of the services used in this tutorial. As a reminder, PG_CONNECTION_STRING is the Postgres connection string for your project from your Sequin account.
Note that the Stytch public token must be prefixed with NEXT_PUBLIC_. This signals to Next.js that the variable should be made available in the browser, while the other environment variables will be kept securely on the server only.
Now, add in the necessary elements to implement Stytch authentication, starting with a library folder containing two components: one that allows you to load the Stytch client, and another that will be used in managing session data.
To do so, create a new lib directory containing a file: loadStytch.js.
.env.local file.
Now, add another file to the lib directory called withSession.js. This file will contain a helper function to create a session stored in your browser’s cookies via a signed and encrypted seal.
pages/components/LoginWithMagicLinks.js, which includes all the UI to send users a Magic Link for login.
./pages/api folder.
Create your first API endpoint by adding a file called authenticate_magic_link.js to the api directory. Then add the code below to authenticate the user from a magic link and create a long-living session:
api/logout.js to delete the user session and effectively log the user out:
handler functions in these authentication endpoints are wrapped in the withSession() helper function to help secure and manage the user’s sessions.
Finally, update the pages/index.js file to display the Stytch login form when a user is not logged in.

withSession helper function, and you are now successfully logged in!
You’re now ready to integrate the frontend with Sequin to retrieve data for each client.
Querying Data Stored by Sequin
Now that your clients are authenticated with Stytch, you can use the email address of each authenticated user to make a PostgreSQL query that retrieves only the projects belonging to that client. In order to accomplish this, you’ll create another API endpoint that queries your Sequin database. First, install the node-postgres package using NPM.pages/api/projects/index.js, import the Stytch client for authorization, and connect to your Postgres database:
/api/projects route is called.
try/catch block.
ANY clause to join clients and projects.
Calling the Project’s Endpoint
Now that you’ve got an endpoint set up, you need to call it from your frontend, but only after a user logs in. You’ll need to include the user’s email and Stytch session token in the request body for authentication. In theHome class you created in pages/index.js, add the following:
/api/projects.

Displaying Projects in the Portal
Now that you’re able to authenticate a user and retrieve their projects from Sequin’s Postgres replica, you’re ready to display the results in the UI. Next.js already includes some basic styling, but don’t feel limited by it. One of the big advantages of building a custom portal like this is that you have complete control over the user interface and experience. Open yourpages/index.js file again and add the following within the code that checks whether a user is logged in:

Writing Data with Sequin
Your clients will probably need to sign off on each project as it’s completed. To let them do this in your new portal, you can add a checkbox on each project that lets clients mark projects as complete.
UPDATE queries to make changes in Airtable.
Fortunately, Sequin has a solution to this limitation. By using their proxy server instead of the standard Airtable API server, your updates will be instantly saved to both Airtable and your Postgres database.
To use the Sequin proxy in JavaScript, install the Airtable NPM package:
pages/api/projects/[projectId].js and add the following:
endpointUrl. This routes requests through Sequin to keep your Postgres database up-to-date at the same time as the Airtable base.
Next, you need a checkbox in your template and a method to call the new endpoint from the frontend. Add this method to your Home component before the return statement:



