Build & Deployment Guide

Complete guide to building and deploying the Cascadia Marquee website

Build & Deployment Guide

Complete guide to building and deploying the Cascadia Marquee website.

Development Commands

Core Development Commands

# Start development server with hot reload
pnpm dev
 
# Build for production
pnpm build
 
# Start production server
pnpm start
 
# Type check without building
pnpm type-check

Content Management Commands

# Build content (MDX processing)
pnpm build:content
 
# Build component registry
pnpm build:registry

Code Quality Commands

# Lint code
pnpm lint
 
# Fix linting issues automatically
pnpm lint:fix
 
# Check import order and fix
pnpm lint:imports

Build Process

Development Build

The development server (pnpm dev) performs the following steps:
  1. Build Registry - Generates component registry
  2. Build Content - Processes MDX files with Contentlayer2
  3. Start Next.js Dev Server - Launches with Turbo mode
pnpm run build:registry && pnpm run build:content && next dev --turbo

Production Build

The production build (pnpm build) includes:
  1. Registry Generation - Builds component registry
  2. Content Processing - Processes all MDX content
  3. Next.js Build - Optimizes and bundles the application
  4. Static Generation - Generates static pages where possible
pnpm run build:registry && pnpm run build:content && next build

Build Output

The build process generates:
.next/
├── static/                 # Static assets
├── server/                 # Server-side code
├── standalone/             # Standalone build (if configured)
└── cache/                  # Build cache
 
.contentlayer/              # Generated content types
src/__registry__/           # Component registry

Content Processing

Contentlayer2 Build

The content build process:
  1. Scans content directory for MDX files
  2. Processes front matter and generates types
  3. Transforms MDX with plugins (syntax highlighting, etc.)
  4. Generates TypeScript types for content
  5. Creates content index for routing

MDX Processing Pipeline

// contentlayer.config.ts
export default makeSource({
  contentDirPath: "./src/content",
  documentTypes: [Doc, Post, LegalDoc, Service],
  mdx: {
    remarkPlugins: [remarkGfm, codeImport],
    rehypePlugins: [rehypeSlug, rehypeComponent, rehypePrettyCode, rehypeAutolinkHeadings],
  },
});

Component Registry Build

The registry build process:
  1. Scans component directories (charts, examples)
  2. Generates lazy-loaded imports for each component
  3. Creates registry index with component metadata
  4. Enables dynamic component loading

Deployment

The site is configured for automatic deployment on Vercel:

Automatic Deployment

  • Main branch → Production deployment
  • Pull requests → Preview deployments
  • Environment variables configured in Vercel dashboard

Vercel Configuration

// vercel.json (if needed)
{
  "buildCommand": "pnpm build",
  "outputDirectory": ".next",
  "installCommand": "pnpm install",
  "framework": "nextjs"
}

Environment Variables

Configure these in Vercel dashboard:
# Canonical app URL (OAuth callbacks use APP_URL + fixed paths)
APP_URL=https://your-domain.com
NEXT_PUBLIC_APP_URL=https://your-domain.com
 
# Google Calendar Integration (redirect URI is built from APP_URL: .../api/google-calendar/oauth/callback)
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour private key here\n-----END PRIVATE KEY-----\n"
GOOGLE_CALENDAR_ID=your-email@gmail.com
 
# Email Service
RESEND_API_KEY=your_resend_api_key
 
# Analytics
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
NEXT_PUBLIC_CLARITY_PROJECT_ID=
 
# Facebook Pixel
FACEBOOK_PIXEL_ID=your_pixel_id

Manual Deployment

Build Locally

# Install dependencies
pnpm install
 
# Build the application
pnpm build
 
# Start production server
pnpm start

Deploy to Other Platforms

Netlify:
# Build command
pnpm build
 
# Publish directory
.next
Railway:
# Build command
pnpm build
 
# Start command
pnpm start
Docker:
FROM node:18-alpine
 
WORKDIR /app
 
COPY package*.json ./
RUN npm install
 
COPY . .
RUN npm run build
 
EXPOSE 3000
 
CMD ["npm", "start"]

Performance Optimization

Build Optimizations

Next.js Optimizations

// next.config.ts
const nextConfig = {
  // Enable experimental features
  experimental: {
    optimizePackageImports: ["lucide-react"],
  },
 
  // Image optimization
  images: {
    formats: ["image/webp", "image/avif"],
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.unsplash.com",
      },
    ],
  },
 
  // Bundle analysis
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        ...config.resolve.fallback,
        fs: false,
      };
    }
    return config;
  },
};

Content Optimization

  • MDX processing with syntax highlighting
  • Image optimization with next/image
  • Font optimization with next/font
  • Code splitting for better performance

Runtime Optimizations

Static Generation

// Generate static pages at build time
export async function generateStaticParams() {
  const posts = await getPosts();
  return posts.map((post) => ({
    slug: post.slug,
  }));
}

Dynamic Imports

// Lazy load heavy components
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Loading...</p>,
});

Image Optimization

import Image from "next/image";
 
// Optimized image loading
<Image
  src="/blog-images/example.webp"
  alt="Description"
  width={800}
  height={600}
  priority={false} // Only for above-the-fold images
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>;

Monitoring & Analytics

Google Analytics 4

GA4 loads from src/components/analytics/google-analytics.tsx after the visitor accepts Analytics cookies. Configure NEXT_PUBLIC_GA_MEASUREMENT_ID (and optionally Clarity) in your deployment environment.
For events, consent gating, and GA4 setup, see the Analytics & Tracking guide.

Error Monitoring

Error Boundaries

import { ErrorBoundary } from "react-error-boundary";
 
function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div role="alert">
      <h2>Something went wrong:</h2>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}
 
export default function App() {
  return (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <MyApp />
    </ErrorBoundary>
  );
}

Security

Environment Variables

  • Never commit .env.local to version control
  • Use Vercel dashboard for production environment variables
  • Rotate keys regularly for security
  • Use least privilege for API permissions

Content Security Policy

// next.config.ts
const nextConfig = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [
          {
            key: "Content-Security-Policy",
            value:
              "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';",
          },
        ],
      },
    ];
  },
};

API Security

// API route with rate limiting
import { rateLimit } from "@/lib/rate-limit";
 
export default async function handler(req, res) {
  try {
    await rateLimit(req);
    // Handle request
  } catch (error) {
    res.status(429).json({ error: "Too many requests" });
  }
}

Troubleshooting

Build Issues

"Module not found" errors:
# Clear cache and reinstall
rm -rf node_modules .next
pnpm install
pnpm build
Content not building:
# Rebuild content specifically
pnpm build:content
Type errors:
# Check TypeScript
pnpm type-check

Deployment Issues

Environment variables not working:
  • Check Vercel dashboard configuration
  • Verify variable names match exactly
  • Ensure no extra spaces or quotes
Build failing on Vercel:
  • Check build logs in Vercel dashboard
  • Verify Node.js version compatibility
  • Check for memory limits
Images not loading:
  • Verify image paths are correct
  • Check next/image configuration
  • Ensure images are in public directory

Performance Issues

Slow build times:
  • Use --turbo flag for development
  • Check for unnecessary dependencies
  • Optimize content processing
Large bundle sizes:
  • Use dynamic imports for heavy components
  • Analyze bundle with @next/bundle-analyzer
  • Remove unused dependencies

Best Practices

Development

  1. Use development commands for local development
  2. Test builds locally before deploying
  3. Keep dependencies updated regularly
  4. Monitor build performance and optimize as needed

Deployment

  1. Use automatic deployments for consistency
  2. Test preview deployments before merging
  3. Monitor production performance with analytics
  4. Keep environment variables secure and up-to-date

Maintenance

  1. Regular security updates for dependencies
  2. Monitor error rates and performance metrics
  3. Backup content and configuration
  4. Document deployment procedures for team members
For questions about build and deployment, check the other documentation sections or contact the development team.