rembrembdocs

Next.js Plugin

Automatically expose your Next.js dev server via OutRay tunnel

The @outray/next plugin automatically creates an OutRay tunnel when your Next.js development server starts, giving you a public URL to share your local development environment.

npm install @outray/next
pnpm add @outray/next
yarn add @outray/next

Wrap your Next.js configuration with the plugin:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray({
  // your Next.js config
})

When you run next dev or npm run dev, you'll see your tunnel URL printed in the terminal:

  ➜  Local:   http://localhost:3000
  ➜  Tunnel:  https://abc123.outray.dev

The plugin accepts an options object as the second argument:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {
    // your Next.js config
  },
  {
    subdomain: 'my-app',
    apiKey: process.env.OUTRAY_API_KEY,
  }
)

Options

OptionTypeDefaultDescription
subdomainstringRequest a specific subdomain for your tunnel URL. Requires authentication.
customDomainstringUse a custom domain. Must be configured in the OutRay dashboard first.
apiKeystringprocess.env.OUTRAY_API_KEYAPI key for authentication.
serverUrlstringwss://api.outray.dev/OutRay server WebSocket URL. Only change this for self-hosted instances.
enabledbooleanprocess.env.OUTRAY_ENABLED !== "false"Enable or disable the tunnel.
silentbooleanfalseSuppress tunnel status logs.
onTunnelReady(url: string) => voidCallback fired when tunnel is successfully established.
onError(error: Error) => voidCallback fired when tunnel encounters an error.
onClose() => voidCallback fired when tunnel connection is closed.
onReconnecting() => voidCallback fired when tunnel is attempting to reconnect.

The plugin respects the following environment variables:

VariableDescription
OUTRAY_API_KEYAPI key for authentication (fallback for apiKey option)
OUTRAY_SUBDOMAINSubdomain to use (fallback for subdomain option)
OUTRAY_SERVER_URLServer URL (fallback for serverUrl option)
OUTRAY_ENABLEDSet to "false" to disable the tunnel
PORTThe port your Next.js dev server runs on (default: 3000)

Custom Subdomain

Reserve a consistent subdomain for your project:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {
    // your Next.js config
  },
  {
    subdomain: 'my-app',
    apiKey: process.env.OUTRAY_API_KEY,
  }
)

Custom Domain

Use your own domain for the tunnel:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    customDomain: 'dev.example.com',
    apiKey: process.env.OUTRAY_API_KEY,
  }
)

Conditional Enabling

Only enable the tunnel in certain environments:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    enabled: process.env.EXPOSE_TUNNEL === 'true',
  }
)

With Callbacks

React to tunnel events in your application:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    onTunnelReady: (url) => {
      console.log(`Share this URL: ${url}`)
    },
    onError: (error) => {
      console.error('Tunnel error:', error.message)
    },
    onReconnecting: () => {
      console.log('Connection lost, reconnecting...')
    },
  }
)

Silent Mode

Disable all tunnel logs:

// next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    silent: true,
    onTunnelReady: (url) => {
      // Handle the URL silently
    },
  }
)

With Other Plugins

Compose with other Next.js plugins:

// next.config.ts
import withOutray from '@outray/next'
import withBundleAnalyzer from '@next/bundle-analyzer'

const config = {
  // your Next.js config
}

export default withOutray(
  withBundleAnalyzer({ enabled: process.env.ANALYZE === 'true' })(config),
  {
    subdomain: 'my-app',
  }
)

App Router & Pages Router

The plugin works seamlessly with both Next.js App Router and Pages Router. No additional configuration is required.

The plugin supports Next.js versions 13.x, 14.x, and 15.x.

Tunnel not starting

Authentication errors

Connection issues

Turbopack compatibility

The plugin works with both webpack and Turbopack. The tunnel is started during the webpack configuration phase, which runs even when using Turbopack for development.