User Authentication with Next.js

Every application has users. This page introduces you to the basics of Nile's drop-in user management in the context of a Next.js application.

Sign up for an invite to Nile if you don't have one already and follow the prompts to create a workspace and database.

1. Clone the example application:

git clone https://github.com/niledatabase/niledatabase.git
cp -r niledatabase/examples/user_management/email_login/NextJS ./nile-email-login
cd nile-email-login

2. Configure your application.

The app uses Nile's SDK and UI Kit which need to be configured with your workspace and database name.

In the project root, rename .env.local.example to .env.local, and open it for editing. You'll provide the NEXT_PUBLIC_WORKSPACE and NEXT_PUBLIC_DATABASE values. You can get these from the Nile Console

  1. Open your database in the dashboard.
  2. The breadcrumbs in the header display your workspace slug and database name.
  3. Enter the workspace slug as the NEXT_PUBLIC_WORKSPACE in .env.local.
  4. Enter the database name as the NEXT_PUBLIC_DATABASE in .env.local.

You'll see these values used in two places:

  • /nile/Server.ts - this configures the connection to Nile's API server
  • /nile/ui/NileContext/index.tsx - this configures the NileProvider that wraps all Nile UI components

3. Run, Sign Up and Query Users

Let's run the application to see things working, and then we'll look under the hood to see how they work.

  1. Run npm run dev, yarn dev, or pnpm dev to start the server.
  2. Open http://localhost:3000/sign-up.
  3. Enter an email address and password, and click Sign up.

If you're configuration is correct, you'll see the success response from the Nile API.

Login to the Nile Console, select your database, and open the SQL editor. Query your users table:

SELECT * FROM users.users;

You should see a record with your newly created user.

4. Dig Deeper

Let's walk through the sign-up flow, from front-end to back-end:

The SignUpForm

Open /app/sign-up/page.tsx to find a simple landing page that wraps a SignUpForm component:

import SignUp from "@/nile/ui/SignUpForm";

export default function SignUpPage() {
  return (
    <main className={styles.main}>
      <SignUp />
    </main>
  );
}

The SignUpForm (in /nile/ui/SignUpForm/index.tsx) provides some basic UI and a couple of key components:

  • The <NileContext> wrapper that provides configuration to nested components
  • The <UserSignupForm> from the Nile UI Kit
import { UserSignupForm } from '@theniledev/react';
...

export default function SignUp() {
  const [res, setRes] = useState({});
  return (
    <NileContext>
      <Stack gap={2} sx={{ maxWidth: '40ch' }}>
        ...
        <UserSignupForm
          onSuccess={(response) => {
            setRes(response);
          }}
        />
        ...
      </Stack>
    </NileContext>
  );
}

The <UserSignupForm> calls an endpoint on your API with a payload containing signup details. That means your API server needs to handle the request. We'll look at that next.

Why do I need an API server? Because of restrictions around 3rd-party cookies and other security concerns, we recommend a dedicated API server on your domain that handles your business logic and makes requests to Nile. Plus it keeps Nile out of your user's view, and your application front and center.

The sign-up route

Open /app/api/sign-up/route.ts:

import { api } from "@/nile/Server";

export async function POST(req: Request) {
  return await api.auth.signUp(req);
}

This API route delegates the request and response to the Nile SDK. If you ever need custom handling for requests or responses, you'd add that here.

The Nile SDK picks up your workspace and database name from the configuration you provided and issues a request to the Nile API. Our API creates a user in your database and generates a JWT for the user, returning it in the response.

5. Login

With your application running, open http://localhost:3000/ and login with the user you created in Step 3.

This is implemented using the same pattern used for sign-up. Open /app/page.tsx to find the LoginForm used, which wraps the <UserLoginForm> from the Nile UI Kit. In /api/login/route.ts you'll again find the request and response delegated to the Nile SDK.

Summary

You've used the basic features of Nile's drop-in user management: user creation and authentication.

Next up: