Powered by

A design system from Family

SIWE — Next.js Implementation

ConnectKit provides a simple way to add Sign In With Ethereum (SIWE) to your Next.js app.

1

Install

Once you've set up ConnectKit, install the official Sign In With Ethereum package and our SIWE helper package to your Next.js project.

Terminal
1npm install siwe connectkit-next-siwe
2

Configure

Our SIWE package includes session handling and route helpers. You'll need to configure them before they can be used. We recommend creating a separate file that you can import into other areas of your app for retrieving session data, etc.

The apiRoutePrefix refers to a new directory you'll create inside your pages/api directory for the SIWE-specific routes.

,
siwe.ts
1import { configureSIWE } from "connectkit-next-siwe";
2
3export const siwe = configureSIWE({
4 apiRoutePrefix: "/api/siwe",
5});

You'll also want to set up an environment variable called SESSION_SECRET—a randomly generated, strong password of at least 32 characters. This is used to encrypt the browser cookie used by the session. Alternatively, you can set the session secret directly with session: { password: ... } } when using configureSIWE.

,
.env
1SESSION_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Add a new catch-all API route to your app inside the directory that we configured with apiRoutePrefix.

It's important that this file be named [...route].ts to take advantage of Next's dynamic routing and because our package expects route as a named query parameter.

,
pages/api/siwe/[...route].ts
1import { siwe } from "../../../siwe";
2export default siwe.apiRouteHandler;

Once configured, wrap your Next.js app using the <siwe.Provider> component, just like you've done previously with the ConnectKitProvider. This lets ConnectKit know that you're using SIWE and how to talk to your API routes.

,
pages/_app.tsx
1import { ConnectKitProvider } from "connectkit";
2import { siwe } from "../siwe";
3
4<siwe.Provider>
5 <ConnectKitProvider {...}>
6 /* Your App */
7 </ConnectKitProvider>
8</siwe.Provider>

And that's it—the ConnectKit modal will now automatically walk your users through how to Sign In With Ethereum after connecting their wallet to your app.

Example

Let's wire up a simple token-gated page. We want to make sure that this page only returns data server-side when the user has verified ownership of their wallet using SIWE and the wallet has collected a specific token.

,
pages/collectors-only.tsx
1import { siwe } from '../siwe';
2
3const walletHasToken = async (address: string): Promise<boolean> => {
4 return // Your implementation of token-gated logic goes here
5}
6
7export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
8 const { address } = await siwe.getSession(req, res);
9
10 if (!address || !(await walletHasToken(address))) {
11 return {
12 redirect: {
13 permanent: false,
14 destination: '/login', // Redirect if wallet does not have the required token
15 },
16 };
17 }
18
19 return {
20 props: {},
21 };
22});
23
24const CollectorsOnlyPage: NextPage = () => {
25 return <>Welcome, collector.</>;
26};
27
28export default CollectorsOnlyPage;

And that's it—we'll leave it to you to implement your token-gating logic in walletHasToken.

API Reference

1configureSIWE({
2 apiRoutePrefix: string,
3 statement?: string, // defaults to "Sign In With Ethereum."
4 session?: {
5 cookieName?: string, // defaults to "connectkit-next-siwe"
6 password?: string, // defaults to `process.env.SESSION_SECRET`
7 cookieOptions?: {
8 secure?: boolean, // defaults to true if `process.env.NODE_ENV === 'production'`
9 // see https://www.npmjs.com/package/cookie for other options
10 },
11 },
12});
apiRoutePrefix
string
Required
statement
string
Default is "Sign In With Ethereum."
session
function
session properties
cookieName
string
Default is "connectkit-next-siwe"
password
string
Default is process.env.SESSION_SECRET
cookieOptions
cookieOptions properties
secure
boolean
Default is true

Defaults to false if process.env.NODE_ENV != 'production'.
See npmjs.com/package/cookie for other options.