Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/outray-tunnel/outray/llms.txt

Use this file to discover all available pages before exploring further.

The @outray/next plugin starts an OutRay tunnel when your Next.js development server boots, printing a public URL alongside the local one — no CLI commands required.
The tunnel only activates when NODE_ENV=development. It is a no-op in production builds.

Setup

1

Install the package

npm install @outray/next
2

Wrap your Next.js config

Import withOutray and wrap your existing config object in next.config.ts:
next.config.ts
import withOutray from '@outray/next'

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

Start the dev server

Run your dev server as usual. The tunnel URL appears alongside the local address:
  Local:   http://localhost:3000
  Tunnel:  https://abc123.outray.dev

Configuration

Pass options as the second argument to withOutray:
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. Requires authentication.
customDomainstringUse a custom domain configured in the OutRay dashboard.
apiKeystringprocess.env.OUTRAY_API_KEYAPI key for authentication.
serverUrlstringwss://api.outray.dev/OutRay server WebSocket URL. Change this only for self-hosted instances.
enabledbooleanprocess.env.OUTRAY_ENABLED !== "false"Enable or disable the tunnel.
silentbooleanfalseSuppress all tunnel status logs.
localbooleanfalseEnable LAN access via mDNS (.local domain) for devices on the same network.
onTunnelReady(url: string) => voidCalled when the tunnel is established.
onLocalReady(info: LocalInfo) => voidCalled when LAN access is available.
onError(error: Error) => voidCalled when the tunnel encounters an error.
onClose() => voidCalled when the tunnel connection closes.
onReconnecting() => voidCalled when the tunnel is attempting to reconnect.

Environment variables

VariableDescription
OUTRAY_API_KEYAPI key for authentication — fallback for the apiKey option.
OUTRAY_SUBDOMAINSubdomain to request — fallback for the subdomain option.
OUTRAY_SERVER_URLServer WebSocket URL — fallback for the serverUrl option.
OUTRAY_ENABLEDSet to "false" to disable the tunnel without removing the plugin.
NODE_ENVThe tunnel only starts when this is development.
PORTThe port your Next.js dev server runs on. Defaults to 3000.

Examples

Custom subdomain

Reserve a consistent URL for your project:
next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    subdomain: 'my-app',
    apiKey: process.env.OUTRAY_API_KEY,
  }
)

Custom domain

Use a domain you’ve configured in the OutRay dashboard:
next.config.ts
import withOutray from '@outray/next'

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

LAN access

Enable mDNS so other devices on your local network can reach the dev server:
next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    local: true,
    onLocalReady: (info) => {
      console.log(`LAN: ${info.httpUrl ?? info.httpsUrl}`)
    },
  }
)

Callbacks

React to tunnel lifecycle events:
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

Suppress all console output and handle the URL yourself:
next.config.ts
import withOutray from '@outray/next'

export default withOutray(
  {},
  {
    silent: true,
    onTunnelReady: (url) => {
      // store or forward url as needed
    },
  }
)

Composing with other plugins

withOutray is a standard Next.js config wrapper and composes normally:
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',
  }
)

TypeScript

The package exports OutrayPluginOptions for typed configuration:
next.config.ts
import withOutray from '@outray/next'
import type { OutrayPluginOptions } from '@outray/next'

const outrayOptions: OutrayPluginOptions = {
  subdomain: 'my-app',
  apiKey: process.env.OUTRAY_API_KEY,
  onTunnelReady: (url: string) => {
    console.log(`Tunnel ready: ${url}`)
  },
}

export default withOutray({}, outrayOptions)
The full OutrayPluginOptions interface:
interface OutrayPluginOptions {
  subdomain?: string
  customDomain?: string
  apiKey?: string
  serverUrl?: string
  enabled?: boolean
  silent?: boolean
  local?: boolean
  onTunnelReady?: (url: string) => void
  onLocalReady?: (info: {
    hostname: string
    ip: string
    httpUrl?: string
    httpsUrl?: string
  }) => void
  onError?: (error: Error) => void
  onClose?: () => void
  onReconnecting?: () => void
}

Compatibility

  • Next.js: 13.x, 14.x, 15.x
  • Routers: App Router and Pages Router
  • Bundlers: webpack and Turbopack
The tunnel is started during the webpack configuration phase, which runs even when using Turbopack.

Troubleshooting

Tunnel not starting
  • Confirm you’re running next dev (not next build or next start).
  • Check that OUTRAY_ENABLED is not set to "false".
  • Verify the PORT variable matches your dev server port.
Authentication errors
  • Run outray login to authenticate, or set OUTRAY_API_KEY.
Connection issues
  • The plugin reconnects automatically on connection loss.
  • Confirm the server URL is correct (default: wss://api.outray.dev/).

Build docs developers (and LLMs) love