Search code examples
react-nativeexpongrok

Is it possible to start expo on a custom domain?


I am trying to develop React Native app using Code Server hosted in the cloud.

Is it possible to run expo with a custom domain, so I can access the link using a mobile device? By default, expo is waiting on exp://10.0.0.186:19000, and it is not accessible over the Internet.

I can specify a custom port using expo start --port XXX, but I don't know if I can specify a custom domain?

I tried using --tunnel switch, but it does not work and it outputs:

Error starting ngrok: /usr/lib/node_modules/expo-cli/node_modules/xdl/binaries/linux/adb/adb: 1: Syntax error: Unterminated quoted string
Tunnel URL not found (it might not be ready yet), falling back to LAN URL.

Solution

  • The --tunnel option usually just works, assuming you've also installed the @expo/ngrok package globally, per the Expo installation tunneling docs.

    Custom domain - Problem

    At the time of this writing @expo/cli doesn't provide a direct way to use a custom domain, unfortunately. They do provide a way to use sub-domains (see below the solution)

    Custom domain - Solution

    However, if you're like me and aren't satisfied with that answer, you can take matters into your own hands:

    1. Get an ngrok account and setup your custom domain (This will require purchasing a personal plan or higher)
    2. Patch @expo/cli to use your custom domain.

    Depending on your package manager, you can use something like pnpm patch or patch-package to create a patch file and ensure it is updated each time you install your node modules.

    For @expo/cli version 0.7.3, the file you'll want to modify is located in node_modules/@expo/cli/build/src/start/server/AsyncNgrok.js and will contain the following:

    const url = await instance.connect({
        ...urlProps,
        authtoken: NGROK_CONFIG.authToken,
        ...
    

    Change it to override the hostname and authToken, and remove the spread of urlProps:

    const url = await instance.connect({
        hostname: "<your custom domain>",
        authtoken: process.env.NGROK_AUTH_TOKEN,
        ...
    

    I'd suggest using an environment variable rather than directly in the patch file which will be committed to your repository.

    Save the file then create and apply your patch file. You should be good to use the expo start --tunnel command as normal with your custom ngrok domain configuration.

    Sub-domains

    Not a valid answer to the OP's question, but in case you don't want to purchase a domain and ngrok subscription for the above solution, you can use a sub-domain with the EXPO_TUNNEL_SUBDOMAIN environment variable, see Expo environment variables docs

    EXPO_TUNNEL_SUBDOMAIN - Disable using exp.direct as the hostname for --tunnel connections. This enables https:// forwarding which can be used to test universal links on iOS. This may cause unexpected issues with expo-linking and Expo Go. Select the exact subdomain to use by passing a string value that is not one of: true, false, 1, 0.

    Which can easily be added to your .env file or package.json start script, for example:

    "start": "EXPO_TUNNEL_SUBDOMAIN=yoursubdomain expo start --tunnel"