Next.js
Quickstart

Quickstart

Learn how to create a Next.js project, install ROQ BaaS SDK, add signup button, login button, and query data from the ROQ BaaS.

Prerequisites

Before we can begin, we must first create an initial project. Please create a new project by visiting ROQ AI Assistant (opens in a new tab). This initial project will create a Backend-as-a-Service or BaaS instance that provides APIs.

After creating the project, you will receive an email invitation to access the project console. Accept the invitation, go to the project console and sign up if you don't have an account on ROQ Console (opens in a new tab).

Create a Next.js application

To create a new Next.js project. Run this command:

npx create-next-app@latest

And the follow along the installation questions:

question

We will use Next.js project with Page Router feature in this quickstart.

Install ROQ BaaS SDK

Install the necessary ROQ BaaS SDK for our project, which is @roq/nextjs and @roq/cli packages.

npm install @roq/nextjs --save
npm install @roq/cli --save-dev

Copy .env from ROQ Console

Besides SDK, we need to copy the environment file from the ROQ Console. Go to the project console (opens in a new tab) and select the project and the environment then copy the environment values from the console.

For local development, we can use the Local Development environment.

copy env from console

After copy the environment values, create file .env in the root directory of the Next.js project and paste the environment values. It is recommended to change the ROQ_SECRET environment value into a more secure value. The default value is CHANGE_THIS_SECRET.

Make sure to include the .env file in the .gitignore file. So that the environment variables are not exposed to the public.

Generate SDK

Our Next.js project will work with ROQ by using a customized generated SDK. This process is necessary to generate Prisma types for SDK.

To generate the SDK, run the command below:

npx @roq/cli generate

If any changes are made to the project schema or entities after the project creation and SDK generation, we can update the SDK by running the command npx @roq/cli generate again. To modify the project schema, we can use the Schema Editor available on the ROQ Console.

The command generates a customizable SDK based on the Prisma BaaS schema and chosen environment. The default location for the code generated is src/lib/roq.

generate roq sdk

The tsconfig.json file in the root directory of the Next.js project should be updated by adding src/lib/* to the paths key, allowing the new SDK to be recognized:

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "paths": {
      "@/*": ["./src/*"],
      "lib/*": ["./src/lib/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Configure Next.js with ROQ authentication

Before doing any data-related query, we need to wrap the Next.js application with the <RoqClientProvider> context provider component. This provider enables the components in the application tree to access the customized generated SDK from our earlier command.

You can put this code in the _app.tsx file.

src/pages/_app.tsx
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import { RoqClientProvider } from 'lib/roq'
import { RoqProvider} from '@roq/nextjs';
 
export default function App({ Component, pageProps }: AppProps) {
  const backendHost = process.env.NEXT_PUBLIC_ROQ_API_URL as string
  const platformHost = process.env.NEXT_PUBLIC_ROQ_PLATFORM_URL as string
 
  return (
    <RoqProvider
      config={{
        host: platformHost,
        auth: {
          useRoqAuth: true,
        },
      }}
    >
      <RoqClientProvider backendHost={backendHost} platformHost={platformHost}>
        <Component {...pageProps} />
      </RoqClientProvider>
    </RoqProvider>
  )
}

To make our Next.js project seamlessly work with ROQ Authentication, we need to configure the project first.

Add file pages/api/auth/[...roqAuth].ts and fill with this code:

[...roqAuth].ts
import { RoqAuth } from '@roq/nextjs';
export default RoqAuth({});

After that we can add a signup button, user will be redirected to the other page if the signup process successful.

src/pages/index.js
import { Inter } from 'next/font/google'
import { useRoqClient } from 'lib/roq'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function Home() {
  const roqClient = useRoqClient()
 
  const handleSignUp = async () => {
     await roqClient.signUp('REPLACE', { postLoginRedirect: '/user' })
  }
 
  const handleSignIn = async () => {
     await roqClient.signIn('REPLACE', { postLoginRedirect: '/user' })
  }
 
  return (
    <main className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}>
       <button onClick={handleSignUp} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">SignUp</button>
       <button onClick={handleSignIn} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Login</button>
    </main>
  )
}

The signUp() method will redirect the user to the registration form for the signup process. To specify the registration form variant, substitute the REPLACE placeholder with the corresponding key obtained from the project console.

To get the registration form variant key, go to the project console (opens in a new tab) and select Authentication and then click the Design menu.

get the reg form key

For example, the registration form variant shown is Admin(administrator). This means the registration form variant name is Admin and the key is administrator.

Create another page called user.tsx and fill with this code:

src/pages/user.tsx
import { Inter } from 'next/font/google'
import { useRoqClient } from 'lib/roq'
import { useSession } from '@roq/nextjs'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function Home() {
  const roqClient = useRoqClient()
  const { session } = useSession()
  
  const roles = session?.user.roles || [];
 
  const logoutHandler = () => {
    roqClient.signOut();
  };
 
  return (
    <main className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}>
      <h1>Dashboard</h1>
      <p>You are currently logged in as: { session?.user.email }</p>
      <p>User roles: 
        <ul>
            {roles.map((role, index) => (
                <li key={index}>{role}</li>
            ))}
        </ul>
      </p>
      
       <button onClick={logoutHandler} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Logout</button>
    </main>
  )
}

After successful signup, the page will be redirected to the user page and Next.js will get a token that will be used for any further request to the REST API from ROQ Baas.

For more about authentication, please visit add authentication.

Query data

We can use the useRoqClient() hook from the generated SDK to query user data, such as the user list.

src/pages/user.tsx
import { Inter } from 'next/font/google';
import { useRoqClient } from 'lib/roq';
import { useSession } from '@roq/nextjs';
import { useEffect, useState } from 'react';
 
const inter = Inter({ subsets: ['latin'] });
 
interface User {
	id: string;
	email: string;
	firstName: string | null;
	lastName: string | null;
	roq_user_id: string;
	tenant_id: string;
	created_at: string;
	updated_at: string;
  }
  
interface UserDataResponse {
    data: User[];
    count: number;
}
 
export default function Home() {
  const roqClient = useRoqClient();
  const { session } = useSession();
 
  const [userData, setUserData] = useState<UserDataResponse>({ data: [], count: 0 });
  const roles = session?.user.roles || [];
 
  useEffect(() => {
      const getUserData = async () => {
      const userData = await roqClient.user.findManyWithCount({});
      setUserData(userData);
    };
 
    getUserData();
  }, []);
 
  return (
    <main className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}>
      <h1>Dashboard</h1>
      <p>You are currently logged in as: {session?.user.email}</p>
      <p>
        User roles:
        <ul>
          {roles.map((role, index) => (
            <li key={index}>{role}</li>
          ))}
        </ul>
      </p>
      <p>
        User list:
        <ul>
          {userData?.data?.map((user, index) => (
            <li key={index}>{user.email}</li>
          ))}
        </ul>
      </p>
    </main>
  );
}

Start the Next.js application

Evertything is setup. Now we can start the development server with this command:

npm run dev

And in the browser, go to http://localhost:3000. Sign up and after that, you will be redirected to the user page with the user's email shown on the page.

What's next?