← All posts

NEXT_PUBLIC_SITE_URL Preview Auth: Fix Verification Email Host

· FakeSignup
env varsci-previewauthtesting

When testing signups on preview deployments, confirmation links often break because they hardcode the production NEXT_PUBLIC_SITE_URL. To fix this, ensure your environment variables correctly reflect the preview URL. This prevents users (or your automated tests) from clicking a verification link that points to a non-existent or incorrect deployment.

The issue arises when your application's backend generates confirmation links using a SITE_URL environment variable that is set to your production domain. When a preview deployment spins up (e.g., on Vercel, Netlify, or a custom CI setup), it gets its own unique URL. If the confirmation email still uses the production SITE_URL, the link will be invalid for that preview environment.

Configuring Environment Variables for Preview Auth

Your primary goal is to make sure the NEXT_PUBLIC_SITE_URL (or equivalent) variable is dynamic enough to capture the actual URL of the environment where the code is running. This often involves setting it correctly in your CI/CD pipeline for preview builds.

For instance, if you're using Vercel, it automatically injects environment variables for preview deployments, including VERCEL_URL. You can then configure your application to use VERCEL_URL when it's present.

Here’s a common pattern:

  1. Backend Configuration: Your backend code needs to read the SITE_URL environment variable. If this variable is not set, it should ideally fall back to a reasonable default or throw an error, but for preview environments, it must be set.

  2. Frontend Configuration (if applicable): If your frontend also needs to construct links (though ideally, this should be server-side), it should read a NEXT_PUBLIC_SITE_URL. The NEXT_PUBLIC_ prefix makes it available in the browser.

  3. CI/CD Setup: This is where the magic happens. Your CI/CD script needs to detect if it’s a preview deployment and set the appropriate environment variable.

    • Vercel: Use VERCEL_URL and map it to your NEXT_PUBLIC_SITE_URL. Vercel often handles this automatically if you configure your build settings correctly.
    • Netlify: Use DEPLOY_URL.
    • Custom CI: You might need to dynamically construct the URL based on your CI job name, branch, and the base domain you use for previews. For example, https://my-feature-branch.my-staging.com.

Implementing Dynamic Site URLs

The simplest approach involves a build-time or runtime configuration that prioritizes the most specific URL available.

Example (conceptual Node.js):

// In your server-side code or configuration file
const siteUrl = process.env.VERCEL_URL
  ? `https://${process.env.VERCEL_URL}`
  : process.env.NETLIFY_DEPLOY_URL
    ? `https://${process.env.NETLIFY_DEPLOY_URL}`
    : process.env.CUSTOM_PREVIEW_URL
      ? process.env.CUSTOM_PREVIEW_URL
      : process.env.SITE_URL; // Fallback to a statically defined SITE_URL

// Use this 'siteUrl' when generating confirmation links

For frontend-facing variables like NEXT_PUBLIC_SITE_URL, you'd set it similarly, perhaps in your .env.local or .env.production files and then override them in your CI for preview builds.

Example .env.production:

NEXT_PUBLIC_SITE_URL=https://your-production-app.com

CI/CD Script Snippet (e.g., GitHub Actions):

jobs:
  build-and-deploy-preview:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request' || github.ref != 'refs/heads/main' # Trigger for PRs and non-main branches

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'

    - name: Set Preview Environment Variables
      run: |
        # Vercel example (if not using Vercel's integration)
        if [ -n "$VERCEL_URL" ]; then
          echo "NEXT_PUBLIC_SITE_URL=https://$VERCEL_URL" >> .env.preview
        else
          # Add logic for other platforms or custom domains
          echo "NEXT_PUBLIC_SITE_URL=https://preview.your-app.com" >> .env.preview # Example custom
        fi

    - name: Install dependencies
      run: npm ci

    - name: Build application
      run: npm run build -- --env preview # Pass an env flag if your build process needs it

    # ... deployment steps ...

When you build your application for a preview deployment, the NEXT_PUBLIC_SITE_URL will dynamically point to that specific preview URL. This ensures that any verification emails sent from that deployment contain links that actually work.

Testing Verification Links in Previews

Manually verifying these links in preview environments can be tedious. You need to trigger a signup, wait for the email, and then click the link. The FakeSignup Chrome extension simplifies this process significantly.

When you install FakeSignup on the Chrome Web Store, it provides a temporary email inbox accessible directly within your browser. This means you don't have to switch tabs or manage separate email clients.

To test your NEXT_PUBLIC_SITE_URL configuration:

  1. Deploy to Preview: Trigger a preview deployment of your application.
  2. Trigger Signup: On the preview URL, perform a user signup.
  3. Open FakeSignup: Open the FakeSignup extension's inbox panel.
  4. Locate Email: Find the verification email that was just sent. The extension automatically captures incoming emails for the temporary address it provides.
  5. Verify Link: Click the verification link within the email displayed in the FakeSignup panel. If your NEXT_PUBLIC_SITE_URL is configured correctly for previews, the link will resolve to your preview deployment and successfully verify the user.

If the link fails, it means your environment variable configuration for previews is still pointing to the wrong host. Revisit your CI/CD setup and application configuration to ensure the NEXT_PUBLIC_SITE_URL is dynamically set for each preview build.

Common Pitfalls and Solutions

Pitfall: Forgetting to set NEXT_PUBLIC_SITE_URL for preview builds. Solution: Ensure your CI/CD pipeline has explicit steps to set this variable for preview deployments, using platform-specific variables like VERCEL_URL or DEPLOY_URL, or a custom domain.

Pitfall: Backend uses a hardcoded production URL, not reading the environment variable. Solution: Verify your server-side code that generates email links. It must reliably read the SITE_URL (or equivalent) environment variable that is dynamically set for the current environment.

Pitfall: Frontend constructs links using a hardcoded URL. Solution: If your frontend constructs any part of these critical links, ensure it also respects the NEXT_PUBLIC_SITE_URL environment variable. However, it's generally better to have the backend handle link generation for security and consistency.

Pitfall: Preview deployments are not correctly configured to have unique, accessible URLs. Solution: Ensure your hosting platform (Vercel, Netlify, etc.) is set up to create unique URLs for each preview branch or pull request. This is usually a default setting but worth confirming.

By diligently managing your environment variables, particularly NEXT_PUBLIC_SITE_URL, you ensure that verification emails in preview environments lead users to the correct deployment, making testing and debugging much smoother. The FakeSignup extension streamlines the verification step itself, allowing you to quickly confirm that the link resolution is working as expected.