Before starting development, ensure you have the following tools installed:
- Node.js (latest LTS version recommended)
- pnpm package manager
-
Clone the repository
-
Install dependencies:
pnpm i
-
Start the development server:
pnpm run dev
The development server will start TinaCMS in development mode with Next.js and provide a local URL for testing.
- Next.js 15 - React framework with App Router architecture
- TinaCMS - Git-based headless CMS for content management
- TypeScript - Type-safe JavaScript development
- Tailwind CSS - Utility-first CSS framework
- shadcn/ui - Component library built on Radix UI
- Lucide React - Icon library
loqus-landing/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Homepage
│ ├── blog/ # Blog routes
│ └── [...urlSegments]/ # Dynamic routes
├── components/ # Reusable React components
│ ├── custom/ # Custom business components
│ ├── icons/ # SVG icon components
│ ├── illustrations/ # Complex illustrations
│ ├── layouts/ # Layout components
│ ├── sections/ # Page section components
│ └── ui/ # shadcn/ui components
├── content/ # TinaCMS content files
│ ├── blog/ # Blog posts (JSON)
│ ├── general/ # General settings
│ └── pages/ # Page content
├── tina/ # TinaCMS configuration
│ ├── collection/ # Content collection schemas
│ └── config.tsx # Main TinaCMS config
├── lib/ # Utility functions and constants
└── public/ # Static assets
All changes must be made in feature branches:
-
Create a new branch from
main:git checkout -b feature/your-feature-name
-
Make your changes locally
-
Test thoroughly using the development server
-
Commit your changes with descriptive messages using conventional commits:
git commit -m "feat(components): ✨ add new hero section component" -
Push the branch to GitHub:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub
When you create a PR, GitHub Actions automatically:
- Builds the site with changes from your branch using
pnpm run build - Configures TinaCMS for the preview branch
- Exports static files to
./outdirectory - Commits build artifacts to the
previewbranch - Deploys to GitHub Pages at https://3jane.github.io/loqus-landing
- Adds a comment to the PR with preview and admin links
Environment variables for preview builds:
NEXT_PUBLIC_BASE_PATH=/loqus-landing(GitHub Pages subdirectory)- Development analytics keys
- Branch-specific TinaCMS configuration
After merging to main, GitHub Actions automatically:
- Builds the production site from merged changes
- Uses production environment variables
- Triggers Digital Ocean deployment
- Publishes to https://loqus.ai
Production environment uses:
NEXT_PUBLIC_BASE_PATH=/(root domain)- Production analytics keys
- Main branch TinaCMS configuration
Content is managed through TinaCMS and stored in the content/ directory:
content/
├── blog/ # Blog posts (JSON format)
├── general/ # Site-wide settings and data
└── pages/ # Page-specific content
├── blog/ # Blog listing page
├── l/ # Landing pages
└── index.json # Homepage content
Collections are defined in tina/collection/:
- GeneralCollection (
general.ts) - Site-wide settings, navigation, footer - PageCollection (
page.ts) - Page content with dynamic sections - BlogCollection (
blog.ts) - Blog posts with metadata and content
- Local Development: Access TinaCMS admin at
http://localhost:3000/admin - Preview Environment: Access admin at https://3jane.github.io/loqus-landing/admin
- Production: Access admin at https://loqus.ai/admin
To add a new content collection:
-
Create collection schema in
tina/collection/new-collection.ts:import { Collection } from "tinacms"; export const NewCollection: Collection = { name: "newContent", label: "New Content", path: "content/new-content", fields: [ { type: "string", name: "title", label: "Title", required: true, }, // Add other fields ], };
-
Register in main config (
tina/config.tsx):import { NewCollection } from "./collection/new-collection"; const config = defineConfig({ schema: { collections: [GeneralCollection, PageCollection, BlogCollection, NewCollection], }, });
-
Create content directory:
mkdir content/new-content
Components follow a modular structure:
components/
├── custom/ # Business-specific components
│ ├── component.tsx
│ └── index.ts # Re-exports
├── sections/ # Page sections with schema + view pattern
│ └── section-name/
│ ├── section-name.schema.ts # TinaCMS field definitions
│ ├── section-name.view.tsx # React component
│ └── index.ts # Re-exports
└── ui/ # shadcn/ui base components
Page sections follow a standardized pattern:
- Schema file (
.schema.ts) - Defines TinaCMS fields - View file (
.view.tsx) - React component implementation - Index file (
.ts) - Clean re-exports
Example section structure:
// hero-section.schema.ts
export const heroSectionSchema = {
type: "object",
label: "Hero Section",
name: "heroSection",
fields: [
{
type: "string",
label: "Title",
name: "title",
},
],
};
// hero-section.view.tsx
export const HeroSectionView = ({ data }) => {
return <section>{data.title}</section>;
};
// index.ts
export { heroSectionSchema } from "./hero-section.schema";
export { HeroSectionView } from "./hero-section.view";Required environment variables:
# TinaCMS Configuration
NEXT_PUBLIC_TINA_CLIENT_ID=your_tina_client_id
NEXT_PUBLIC_TINA_BRANCH=main # or feature branch for development
TINA_TOKEN=your_tina_token
# Deployment Configuration
NEXT_PUBLIC_BASE_PATH=/ # Production: /, Preview: /loqus-landing
# Analytics (optional)
NEXT_PUBLIC_SEGMENT_KEY=your_segment_key
NEXT_PUBLIC_SEGMENT_HOST=your_segment_proxy_hostCritical: The application handles different base URLs automatically:
- Production (
https://loqus.ai): Uses/as base path - GitHub Pages Preview (
https://3jane.github.io/loqus-landing): Uses/loqus-landing/as base path
Asset references are handled automatically by Next.js configuration.
Available npm scripts:
# Development with TinaCMS
pnpm run dev
# Production build
pnpm run build
# Local build (skips cloud checks)
pnpm run build-local
# Start production server
pnpm run start
# Static export
pnpm run export
# Linting
pnpm run lintBefore creating a PR, verify:
- Development server runs without errors (
pnpm run dev) - Production build succeeds (
pnpm run build) - All TypeScript errors resolved
- Components render correctly on different screen sizes
- TinaCMS admin interface works with new content types
- Content editing flows work as expected
- No console errors or warnings
- Changes are tested locally
- Code follows project conventions
- Commit messages follow conventional commit format
- Create PR with descriptive title and description
- Wait for automated build and preview deployment
- Test on GitHub Pages preview using provided links:
- Preview site: https://3jane.github.io/loqus-landing
- Content admin: https://3jane.github.io/loqus-landing/admin
- Request review from team members
- Address feedback and update as needed
- Merge after approval and successful automated tests
-
TinaCMS Authentication Errors
- Verify
TINA_TOKENandNEXT_PUBLIC_TINA_CLIENT_IDare set - Check branch configuration matches
NEXT_PUBLIC_TINA_BRANCH
- Verify
-
Build Failures
- Run
pnpm run build-localto skip cloud checks during development - Ensure all TypeScript errors are resolved
- Run
-
Asset Loading Issues
- Verify assets are in the
public/directory - Check base path configuration for different environments
- Verify assets are in the
-
Preview Deployment Issues
- Verify GitHub Actions have proper secrets configured
- Check workflow logs in GitHub Actions tab
For additional support:
- Check existing GitHub Issues
- Review TinaCMS documentation at https://tina.io/docs
- Consult Next.js documentation at https://nextjs.org/docs