nextjs-hackathon-template
nextjs-hackathon-template copied to clipboard
Next.js Template using NextAuth and Descope for authentication
Next.js Hackathon Template
Template Features · Tech Stack · Setup · Descope · Template Data · Airtable Setup · Deploy · Gallery
🪐 The Hackathon template comes with the following full-stack features:
- Descope NextAuth authentication 🔐
- Protected pages & API routes with NextAuth.
- The latest Next.js app router, server & client components.
- Fully customizable Home screen which features an About, Speakers, Sponsors, and FAQ section.
- A dedicated Team page to showcase all contributors.
- A Dashboard page for Hackers to complete onboarding forms, acceptance status, and hackathon announcements.
- Airtable backend for hackers to signup and view hackathon details.
- Fully responsive UI (mobile, tablet, computer).
✨ Made with...
- Descope
- NextAuth
- Flowbite
- Tailwind CSS
- Airtable (Optional)
⚙️ Setup: Local Testing
- In the root directory of the project, copy the
.env.exampleto.envby runningcp .env.example .envand include the following:
NEXTAUTH_SECRET="YOUR_NEXTAUTH_SECRET"
NEXTAUTH_URL="WHERE SERVER IS HOSTED (e.g. http://localhost:3000)"
DESCOPE_PROJECT_ID="YOUR_DESCOPE_PROJECT_ID"
DESCOPE_ACCESS_KEY="YOUR_DESCOPE_ACCESS_KEY"
NEXT_PRIVATE_SECRET_TOKEN="YOUR_SECRET_TOKEN"
DESCOPE_PROJECT_ID- can be found in your Descope's account under the Project pageDESCOPE_ACCESS_KEY- can be generated in your Descope's account under the Access Keys pageNEXTAUTH_SECRETandNEXT_PRIVATE_SECRET_TOKENcan be generated by the following command in your terminal (do not use the same generated value for both):
$ openssl rand -base64 32
NOTE: The
NEXT_PRIVATE_SECRET_TOKENis used to authenticate the request in the API. It is passed as a parameter in the fetch URL.
- Setup SSO
- To enable SSO and add Descope as an Identity Provider (IdP), we need to add our flow hosting URL:
https://auth.descope.io/<YOUR_DESCOPE_PROJECT_ID>
- Navigate to Descope Project --> Authentication methods --> Identity Provider:
- Installation
npm installnpm run dev- Open
http://localhost:3000in your browser
🔑 Descope
To use Descope, we can implement a custom provider.
Out NextAuth options can be found in /app/_utils/options.ts.
In our authOptions we have our custom Descope provider we have attributes such as your clientID (Descope project id), clientSecret (Descope access key), and wellKnown set to Descope's OpenID Connect configuration which contains our authorization endpoints and authentication data.
import { NextAuthOptions } from "next-auth"
export const authOptions: NextAuthOptions = {
providers: [
{
id: "descope",
name: "Descope",
type: "oauth",
wellKnown: `https://api.descope.com/${process.env.DESCOPE_PROJECT_ID}/.well-known/openid-configuration`,
authorization: {
params: { scope: "openid email profile descope.custom_claims" },
},
idToken: true,
clientId: process.env.DESCOPE_PROJECT_ID,
clientSecret: process.env.DESCOPE_ACCESS_KEY,
checks: ["pkce", "state"],
profile(profile, tokens) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
idToken: tokens.id_token,
...tokens,
};
},
},
],
callbacks: {
async jwt({ token, account }) {
if (account?.id_token) {
token.idToken = account.id_token;
}
return token;
},
async session({ session, token, user }) {
// @ts-ignore
session.idToken = token.idToken;
return session;
},
},
}
Note: The purpose of the callbacks at the end, are to be able to fetch the id_token and include it in the NextAuth Session object. You will be able to access custom_claims also through this
id_tokenusing getSession() on the client side.
Then in our /app/api/auth/[...nextauth]/route.ts we pass our authOptions and intialize NextAuth.
import NextAuth from "next-auth/next";
import { authOptions } from "../../../_utils/options";
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
👾 Template Data
The template data can be found in the ./app/_template_data
All the template data can be customized and found in the following files.
To see our template data in action make your way to app/page.tsx.
In the page.tsx we import the different template data and the components from our _components folder. We pass in
our template data into these components as props that then render the data!
📦 Airtable Setup
NOTE: This step is Optional!
To learn more about creating a form and setting up Airtable as a database go to Airtable.md!