SyntaxStudy
Sign Up
Next.js Environment Variables, CI/CD, and Production Checklist
Next.js Beginner 1 min read

Environment Variables, CI/CD, and Production Checklist

Managing environment variables correctly is critical for security and correctness in production. Never commit .env.local to version control — it should be in .gitignore. Use .env.example (committed) to document all required variables without their values. On CI/CD platforms, configure secrets in the platform's secret store and inject them as environment variables during the build step. A production Next.js deployment should have several optimisations in place. Enable output: 'standalone' for Docker or ensure your platform uses the Next.js build cache to speed up rebuilds. Set NEXT_TELEMETRY_DISABLED=1 to disable anonymous telemetry in automated builds. Review the bundle analyser output (using @next/bundle-analyzer) to identify large dependencies that could be replaced or lazy-loaded. Before going live, run through a checklist: verify that all environment variables are set correctly, check that CSP headers are configured, ensure HTTPS is enforced, validate that the sitemap and robots.txt are accessible, test the 404 and 500 error pages, check Core Web Vitals with Lighthouse or PageSpeed Insights, and confirm that ISR and on-demand revalidation work as expected. Next.js build output warns about common issues like missing image width/height and deprecated configuration options.
Example
// next.config.js — production-ready configuration

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
  reactStrictMode: true,
  poweredByHeader: false, // remove X-Powered-By header

  images: {
    formats: ['image/avif', 'image/webp'],
    remotePatterns: [
      { protocol: 'https', hostname: process.env.NEXT_PUBLIC_CDN_HOSTNAME },
    ],
  },

  // Security headers
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'X-DNS-Prefetch-Control', value: 'on' },
          { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
          { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
        ],
      },
    ];
  },
};

module.exports = withBundleAnalyzer(nextConfig);

// .env.example — commit this, not .env.local
// DATABASE_URL=postgresql://user:password@host:5432/dbname
// NEXTAUTH_SECRET=your-secret-here
// NEXTAUTH_URL=https://yourdomain.com
// NEXT_PUBLIC_CDN_HOSTNAME=cdn.yourdomain.com
// REVALIDATE_SECRET=your-revalidation-webhook-secret
// WEBHOOK_SECRET=your-cms-webhook-secret

This is the last lesson in this section.

Create a free account to earn a certificate