Developer guides

Developing with Next.js on GitHub Codespaces

A guide covering step-by-step instructions for developing Next.js applications with Sanity Studio Live Preview on GitHub Codespaces.

Overview

GitHub Codespaces provides a cloud-based development environment, but it presents unique challenges when working with:

  • Dynamic URLs that change per codespace instance.
  • Proxy headers that can cause CORS and Server Actions issues.
  • WebSocket connections that don't work reliably through the Codespaces proxy.

This guide documents solutions to these challenges for a Next.js + Sanity Studio monorepo.

Prerequisites

  • GitHub repository with Next.js and Sanity Studio.
  • Sanity project with project ID, dataset, and API tokens.

Setup

Configure Sanity CORS origins

Sanity's API requires explicit CORS configuration to allow requests from your Codespaces URLs.

Add CORS origins to Sanity

  • Go to https://www.sanity.io/manage.
  • Select your project.
  • Navigate to API > CORS Origins.
  • Add the following origins, replacing YOUR_CODESPACE_NAME with the name of your codespace (the value of $CODESPACE_NAME in the codespace terminal):
    • https://YOUR_CODESPACE_NAME-3333.app.github.dev (Studio)
    • https://YOUR_CODESPACE_NAME-3000.app.github.dev (frontend)
  • For each origin:
    • Click Add CORS origin, enter the origin, and select Allow credentials.
    • Click Save.

Why exact origins instead of wildcards

  • Each codespace has a unique name in its URL, so you add the origins for your own codespace.
  • A wildcard such as https://*.app.github.dev matches every codespace on GitHub, including ones you don't control. With credentials allowed, any of them could make authenticated requests as a logged-in user of your project.
  • Trade-off: When you create a new codespace, add its origins, and remove the old ones.

Security notes

  • Never allow credentials on a platform-wide wildcard such as https://*.app.github.dev. For the full guidance, see "Access your data (CORS)".
  • Remove a codespace's origins when you no longer use the codespace.

Configure port forwarding

Make ports public

GitHub Codespaces ports are private by default, which prevents external services (like Sanity) from accessing your development servers.

Method 1: VS Code UI

  • Open the PORTS tab in the terminal panel.
  • Right-click port 3000, and then select Port Visibility > Public.
  • Right-click port 3333, and then select Port Visibility > Public.

Method 2: CLI

gh codespace ports visibility 3000:public -c $CODESPACE_NAME
gh codespace ports visibility 3333:public -c $CODESPACE_NAME

Why this matters

  • Sanity needs to make requests to your frontend for live preview.
  • Studio needs to load the frontend in an iframe.
  • Private ports block these cross-origin requests.

Set up environment variables

Front-end environment file

Create apps/web/.env and add the following environment variables:

Studio environment file

Create apps/studio/.env and add the following environment variables:

Create API tokens

  • Go to https://www.sanity.io/manage.
  • Select your project.
  • Navigate to API > Tokens.
  • Create tokens:
    • Read token: Viewer role
    • Write token: Editor role

You can give these names like "Codespaces read" and "Codespaces write" to make them easier to recognize in the future.

Code changes for Codespaces compatibility

Detect Codespaces domain

In many cases (especially if using a starter template), the Presentation Tool URL defaults to http://localhost:3000 in development mode, which doesn't work in Codespaces.

Update any helper functions that determine the frontend URL to auto-detect Codespaces environment.

Allow Server Actions from the Codespaces proxy

Next.js blocks Server Actions requests when the origin header doesn't match the x-forwarded-host header. In Codespaces:

  • origin: localhost:3000 (internal routing)
  • x-forwarded-host: codespace-name-3000.app.github.dev (public URL)

This causes 500 errors: x-forwarded-host header does not match origin header from a forwarded Server Actions request. Aborting the action.

To resolve this, configure Next.js to trust Codespaces proxy domains.

File: next.config.ts or next.config.js

What this does

  • Tells Next.js to accept Server Actions from Codespaces URLs.
  • Maintains security by limiting to specific domains.
  • Allows localhost for local development.

Security considerations

  • Wildcards are safe for development environments.
  • In production, use specific domains only.
  • Never use "*" (all origins) in production.

Let's make sure it works

Start development servers

  • Install dependencies.
  • Start both development servers.

Access your applications

Get your URLs (Codespaces URLs follow this pattern: https://{CODESPACE_NAME}-{PORT}.app.github.dev)

Frontend

Select port 3000 in the PORTS tab, or construct manually: https://your-codespace-name-3000.app.github.dev

Studio

Select port 3333 in the PORTS tab, or construct manually: https://your-codespace-name-3333.app.github.dev

Verify

Open Studio (port 3333)

  • You should see the Sanity Studio interface.
  • If you see project ID errors, confirm your .env file has the correct project variables.

Open the Presentation Tool

  • Click Presentation in the Studio toolbar.
  • You should see your frontend loaded in an iframe.

Test live editing

  • Edit content in Studio.
  • Changes should appear in Presentation.

Troubleshooting

Issue: 502 Bad Gateway on port URLs

Cause

Servers aren't running or ports aren't forwarded correctly.

Solution

# Check if servers are running
lsof -i :3000  # Should show Node.js process
lsof -i :3333  # Should show Node.js process

# Test local access
curl http://localhost:3000  # Should return HTML
curl http://localhost:3333  # Should return HTML

# Verify port visibility
gh codespace ports  # Should show both ports as public

Issue: "projectId can only contain only a-z, 0-9 and dashes"

Cause

Environment variables not loaded or .env file missing.

Solution

cd apps/studio

# Check if .env exists
ls -la .env

# Verify project ID is set
cat .env | grep SANITY_STUDIO_PROJECT_ID

# If missing, create .env file with correct values

Issue: Presentation Tool shows a blank screen

Cause

Frontend URL not configured correctly, or CORS issues.

Solutions

  • Check browser console in the presentation iframe (right-click → Inspect).
  • Verify CORS origins for your project include https://YOUR_CODESPACE_NAME-3000.app.github.dev (frontend) and the same URL with port 3333 (Studio).
  • Check frontend is accessible: open port 3000 directly in a new tab.
  • Verify the presentation URL: add console.log(getPresentationUrl()) to debug.

Issue: 500 error "Invalid Server Actions request."

Cause

Origin mismatch between forwarded host and origin headers.

Solution

Verify next.config.ts includes the serverActions.allowedOrigins configuration from the "Allow Server Actions from the Codespaces proxy" section.

Issue: WebSocket connection errors

Cause

This is expected behavior in Codespaces due to the known proxy issues.

Solution

WebSocket errors that appear in the console can be safely ignored. Live editing should still work as expected.

Was this page helpful?