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
- Set up OAuth Providers in Google Cloud Console
- Configure environment variables with OAuth credentials
- Middleware integration handles authentication flow automatically
- Session management provides user context throughout the application
Development Guidelines
Code Quality
- Run
npx eslint src --fixto 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
publicdirectory and add it to the list inmiddleware.ts - Use the design system defined in
.cursor/rules/design-system.mdcfor 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
- User visits the application and authentication is required
- Redirect to OAuth provider (Google) handled by Auth.js
- OAuth callback processes the authentication response
- JWT token creation with user permissions from Core API
- 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);