Skip to main content

Web Frontend Overview

The Cosailor Template web frontend is built with modern technologies including Next.js 15, Auth.js for OAuth integration, and Tailwind CSS for styling.

Tech Stack

  • Next.js 15 (App Router)
  • Auth.js - OAuth middleware for authentication
  • Tailwind CSS 4 - Utility-first CSS framework for styling
  • Shadcn UI - Component library built on Headless UI and Tailwind CSS

Next.js Architecture

Next.js Runtime

ReactJS is a client-side JavaScript library for building user interfaces, where the code is compiled and executed in the user's browser. In contrast, Next.js is a server-side framework built on top of React that enables server-side rendering and other backend capabilities. With Next.js, the code is not just compiled and served statically; it is actually executed on the server (using Node.js), allowing for dynamic content generation and API routes, and improved SEO through pre-rendering. This means that parts of your application can run on the server before being sent to the client, providing a more powerful and flexible architecture compared to traditional React applications.

Server-Side Rendering (SSR)

The /app directory is the root of the Next.js application. By default, Next.js uses Server-Side Rendering (SSR) for all pages, which means that the page is rendered on the server and sent to the client. Therefore, you can directly fetch data from an external API/database in the page component.

For hooks (useState, useEffect, etc.) and client-side interactions, create a client component in the /components directory and mark "use client" at the top of the file.

Environment Variables

If the environment variable name starts with NEXT_PUBLIC_, it will be available on the client side. Otherwise, it will be only available on the server side. Therefore, for client-side variables, please use substitution variables in Cloud Build, and for server-side variables, please use environment variables in Cloud Run.

Auth.js Integration

Auth.js is a middleware that connects with various OAuth providers (Auth0, Okta, Google, Azure, etc.) to handle tokens both frontend and backend. Please refer to the List of Providers for more details. You will need to add OAuth related environment variables.

OAuth Provider Configuration

Google OAuth Setup:

  • AUTH_GOOGLE_ID - Google OAuth client ID
  • AUTH_GOOGLE_SECRET - Google OAuth client secret

Auth.js Configuration:

  • AUTH_SECRET - NextAuth secret, random string (32+ characters recommended)
  • AUTH_TRUST_HOST - Always set to true to trust the host
  • AUTH_URL - The deployed URL of the application, not required for local development

Getting Started with Auth.js

  1. Set up OAuth Providers in Google Cloud Console
  2. Configure environment variables with OAuth credentials
  3. Middleware integration handles authentication flow automatically
  4. Session management provides user context throughout the application

Development Guidelines

Code Quality

  • Run npx eslint src --fix to automatically fix most linting issues
  • Tailwind classes are sorted using eslint-plugin-tailwindcss; running this command enforces the order and helps prevent merge conflicts

UI Customization

  • To add a graphic to the sign-in page, place the image in the public directory and add it to the list in middleware.ts
  • Use the design system defined in .cursor/rules/design-system.mdc for consistent component development

Component Structure

apps/web/
├── app/ # Next.js App Router pages
│ ├── api/ # API routes
│ ├── auth/ # Authentication pages
│ └── (dashboard)/ # Dashboard routes
├── components/ # Reusable UI components
├── lib/ # Utility functions and configurations
│ ├── auth.ts # Auth.js configuration
│ └── core-api-jwt.ts # JWT token handling
├── public/ # Static assets
├── styles/ # Global styles
└── middleware.ts # Next.js middleware

Authentication Flow

Session Handling

  1. User visits the application and authentication is required
  2. Redirect to OAuth provider (Google) handled by Auth.js
  3. OAuth callback processes the authentication response
  4. JWT token creation with user permissions from Core API
  5. Session establishment with user context available throughout the app

Token Management

The frontend handles JWT tokens for Core API communication:

// lib/core-api-jwt.ts
const minimalToken = await mintToken({
email: user.email,
roles: [],
managedUserIds: [],
tenantId: null
});

const snapshot = await fetch(`/api/auth/snapshot?email=${user.email}`, {
headers: { Authorization: `Bearer ${minimalToken}` }
});

const fullToken = await mintToken({
email: user.email,
roles: snapshot.roles.map(r => r.name),
managedUserIds: snapshot.managedUsers.map(u => u.id),
tenantId: snapshot.tenant?.id
});

Integration with Core API

Type-Safe API Calls

The frontend uses auto-generated TypeScript SDKs for type-safe API calls:

import { CoreApiClient } from '@instalily/core-sdk-ts';

const client = new CoreApiClient({
baseUrl: process.env.NEXT_PUBLIC_CORE_API_URL,
authToken: userToken
});

const dashboardData = await client.dashboard.get(userId);