Keep query string for external urls

A user can be sent to the main website by some referral id, using a query string:

www.site.com/?ref=XXX

And when they click on a link to a login area, this query string must go with that external link:

https://internal.site.com?ref=XXX

I am working with wordpress, so I cannot append ?ref=<?php echo $_GET['ref']?> to that link.

I have already changed .htaccess to:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php - [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]
</IfModule>

Every link back to the main website keeps the query strings, but external urls do not.

www.site.com?ref=XXX [original]
www.site.com/go/reds?ref=XXX [query strings are kept]
https://internal.site.com [query strings are removed]

The QSA flag in htaccess should do the trick, but it's not working for external links.


You can do this by adding this script at the end of your page. This code will pass variables to every links on client side.

<p><a href="/about/">Internal</a></p>
<p><a href="https://google.com">External</a></p>
<p><a href="/post/?id=1">Link with query string</a></p>

<script>
    var index = window.location.href.indexOf('?')
    if(index != -1){
        var querystring = window.location.href.slice(index + 1)
        var tagA = document.getElementsByTagName('a');

        for(var i = 0; i < tagA.length; i++){
            var href = tagA[i].getAttribute('href');

            href += (href.indexOf('?') != -1)? '&' : '?';
            href += querystring;

            tagA[i].setAttribute('href', href);
        }
    }
</script>

To apply the custom query everytime a the_permalink() function is called, you can use this filter

function append_query_string($url) {
    if (isset($_GET['ref'])) {
        $url = add_query_arg('ref', $_GET['ref']);
    }
    return $url;
}
add_filter('the_permalink', 'append_query_string');

But it could be inconvenient option 'cause it is applied only to the link generated with the_permalink function, so you have to apply this function also to menus, post type archive link, and, in general, where you generate the link without the wp permalink function.

Another solution could be store the ref inside a session cookie or the $_SESSION global: in this case the reference will be lost everytime the user browser is clodes, so you can track the reference also if the user manually return to your site after been referred.

Hope it helps :)