Jun 10. 2018 · by Helge Sverre

How to use Ngrok with CraftCMS

ngrok is a handy tool that let's you create temporary links which tunnels through your firewall and all that network magic that I don't understand, into your local web server; without you having to configure your router or port forwarding, this is handy to share previews of local development sites with clients or teammates, I've written a blog post about ngrok on my personal website a while ago that you can check out for a quick tutorial on how to use it.

However there is a problem with ngrok that you will occur when using it in conjunction with CraftCMS and often other CMS' (ex: WordPress), the links that are generated by the system ( ex: {{ entry.url }} ) often still use the whatever.local development domain, instead of the ngrok preview url (somerandomstring.ngrok.io), causing links to point to an non-existent page.

To solve this, we have to do some trickery with the config files and the image path aliases.

Craft 2

config/general.php
PHP
<?php

$isNgrok = array_key_exists("HTTP_X_ORIGINAL_HOST", $_SERVER) && strpos($_SERVER["HTTP_X_ORIGINAL_HOST"], "ngrok");
$host = 'http://' . $_SERVER[$isNgrok ? 'HTTP_X_ORIGINAL_HOST' : 'SERVER_NAME'] . '/';

return array(
    // ...

    '.dev' => [
        'devMode' => true,
        'siteUrl' => $host,
        'environmentVariables' => array(
            'baseUrl' => $host,
        ),
    ],

    // ...
);

A problem that might arrise when doing this in Craft 3, is that image paths that uses a Yii Aliases in the path will still point to the local domain, and the CP admin submit url also points to the local site, so to fix this you can override the alias and the baseCpUrl in your general.php file as such:

Craft 3

config/general.php
PHP
<?php

$isNgrok = array_key_exists("HTTP_X_ORIGINAL_HOST", $_SERVER) && strpos($_SERVER["HTTP_X_ORIGINAL_HOST"], "ngrok");
$host = 'http://' . $_SERVER[$isNgrok ? 'HTTP_X_ORIGINAL_HOST' : 'SERVER_NAME'] . '/';

return [
    // More config here...
    'dev' => [
        // Dev Mode (see https://craftcms.com/support/dev-mode)
        'devMode' => true,

        'siteUrl' => $host,
        'baseCpUrl' => $host,
        'aliases' => [
            '@web' => $host,
        ],

        // Logging in to the CP will fail unless you turn off CSRF protection.
        'enableCsrfProtection' => false,
    ],
]

If you've done everything correctly, the next time you start ngrok and point it to your local CraftCMS website, all dynamically generated links (to entries, assets and the CP login form) should be using the ngrok url as the base path.

Start an ngrok tunnel
BASH
ngrok http -host-header=client-project.test 80