Generating Root Short URLS From A YOURLS Subdirectory Install

With my increased use of Twitter I find myself tweeting links to articles quite often. But when space is limited to 120 characters and URLs are long one runs out of space to add the link quite easily. The standard way around this is to use an URL shortening service and post shortened URLs. I’ve used one of the more popular URL shorteners,, for the last couple of years.

Though I was satisfied with it always bothered me to be dependant on a service. What would happen to my links if the service went away? Or if their Libyan top level domain (.ly) was taken away? All my posted URLs would no longer work! So I made the decision a while ago to use my own URL shortener so I have complete control. And a couple of weeks ago I finally got around to implementing it.

The shortner I’m using is YOURLS. It was quite easy to install and is well documented in many other places (most notably, perhaps, on Lifehacker) so I won’t go into details about that process here.

Though getting started was simple I still had some issues. The most notable was based on my preference to segregate apps on my web space. I wanted all of the files from YOURLS to be placed in a subdirectory (so I wouldn’t accidentally remove required files from the root accidentally while cleaning up). But that lead to short URLs that included the subdirectory of the install. Who wants URLs like is so much more convenient as it uses fewer characters.

The answer to this dilema was to change the .htaccess file in the root to add the following rewrite rule:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9A-Za-z]+)/?$ /subdir/yourls-go.php?id=$1 [L]
RewriteRule ^([0-9A-Za-z]+)+/?$ /subdir/yourls-infos.php?id=$1 [L]
RewriteRule ^([0-9A-Za-z]+)+all/?$ /subdir/yourls-infos.php?id=$1&all=1 [L]

With this rule in place would be the same as using

This is a nice, simple solution and works great but there’s still a problem. YOURLS still generated short URLs with the subdirectory so I had to manually edit the short URL before pasting it to where I wanted to use it. This annoyance would also affect URLs shortened by my Twitter client (which I had set up to use YOURLS as it’s URL shortener). (The instructions here are for Tweetdeck but are similar for other clients.)

This was an annoyance I didn’t want to deal with every time I wanted to post a link so I set about reviweing the YOURLS PHP code in the hopes of finding a way to have YOURLS generate short URLs with the subdirectory already removed. And I found it.

The real meat of YOURLS is functions.php which can be found in the includes directory of the YOURLS installation. I found that functions.php uses a setting from the YOURLS config file called YOURLS_SITE, to return the short URL of a given link and other various related functionality. (This setting is manually set when installing YOURLS.) I simply replaced YOURLS_SITE with a substring of YOURLS_SITE in all but two functions that use it (yourls_admin_url() and yourls_site_url() functions).

For our purposes let’s say that YOURLS_SITE is set to “” (where “subdir” is the name of the directory where YOURLS is installed). Substitute the following code every time YOURLS_SITE is mentioned (except for the two functions mentioned at the end of the previous paragraph):

substr(YOURLS_SITE, 0, 18);

This essentially replaces “” with “” (the first 18 characters of “”). The number 18 will be different depending on the length of your domain name (for instance, “” is 19 characters so I used the number 19).

Now I have my YOURLS installation in it’s own subdirectory but am able to generate and use short URLs from the root.


If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.


I don’t get it. You replaced the YOURLS_SITE code with what? Can you please show an example? I have found 19 YOURLS_SITE code in the functions.php file.

As the post said I replaced “YOURLS_SITE” with “substr(YOURLS_SITE, 0, X)” where X is the number of characters in the URL before the subdirectory is mentioned. All occurences in functions.php were replaced except for those in the yourls_admin_url() and yourls_site_url() functions.

Thanks Dave.

I’ve got the subdir removed from the URL. But somehow the link doesn’t work. It gives me this error “URL is a short URL”. I’ve replaced exactly 15 YOURLS_SITE except for “function yourls_admin_url” and “function yourls_site_url”.

I also have RewriteRule ^(.*)$ /somedir/yourls-loader.php [L] in the root httaccess file.

Put all the rewrite rules mentioned in the post in the .htaccess file in your root.

This was brilliant. I’ve got it working (although I haven’t tried the Twitter changes yet), but do you know how I can get the Bookmarklets and the Prefix-n-Shorten to work? Thanks.

BadKiwi –

For the bookmarklets, just drag the ones you want from the webpage to the bookmark toolbar in your browser.

For Prefix-n-Shorten, when you’re on a page you want a short URL for just put the URL of your YOURLs installation in the address bar before the URL you want to shorten.

Thanks. Just to clarify. What I meant was that the Bookmarklets were still using the subdirectory URL and not the Root URL. I had dragged the Bookmarklets onto the bookmark toolbar after setting up as per your suggestion. They’re working now. I think it was just that I needed to restart Firefox.

The Prefix-n-Shorten isn’t yet working as Root though. If I do I get a 404 error. If I do I get it going to my Yourls site. My Yourls Tools page also still tells me to use Do you know which file I can alter to correct this?

I have to say. Yourls is amazing and your Root URLs setup is the icing on the cake. Thank you.

BadWiki- I get the same 404 error on Prefix-n-Shorten but I actually never used it until your comment came up. I’ll look into it.

Sorry, Dave. I spoke too soon about the Bookmarklets. Shorten and Custom Shorten work, but Instant Shorten and Custom Instant Shorten do not. It’s no biggie, but it would be nice to get those working too. Kind regards.

great article and it seems to be working for me.. although instead of replacing YOURLS_SITE with substr(YOURLS_SITE, 0, X)

I decided to define another variable called YOURLS_SITEADMIN inside config.php and then replace only TWO instances of YOURLS_SITE with YOURLS_SITEADMIN in functions.php inside yourls_admin_url() and yourls_site_url() functions.

This is exactly what I was looking for but not quite sure about a couple things. I edited the .htaccess file and then started digging around the config and functions files to find where to replace YOURLS_SITE with the substring but not knowing much PHP, I got a bit confused with simple things such as ; and ‘ and whether they belong or not. I know results in 16 but where exactly to I place substr(YOURLS_SITE, 0, 16)? An exact example would help me tremendously.

Also, I when I had to access the admin part of my site (, it redirected to! Is this because I wasn’t finished or will it happen for all subdirs bc of the rewrite in the htaccess?

I truly appreciate you taking the time to figure this out and more so for posting it for all of us to find! Thanks!

Felix –

This is all mentioned in the post. Put the substr function every place YOURLS_SITE is mentioned in functions.php except for within the yourls_admin_url() and yourls_site_url() functions. It also says to replace YOURLS_SITE with substr(YOURLS_SITE, 0, 18). I don’t know how much more ‘exact’ I can get but if you still have a question about this let me know.

As for the admin question I don’t understand what you’re asking. If you install YOURLS in then the admin is in Not sure if that helps. Again, please be specific about your question. Give information about your setup so I can understand what you mean.

– Dave

Now, stats links doesn’t work for me 🙁

underback –

I’m getting stats from my installation. It’s possible that your host has your environment set up differently. Do you get stats when you set YOURLs up normally? How are you trying to access your stats?

– Dave

Hey Dave. This all worked like a charm…. BUT (haha, always a but) now that stats pages (http://shorturl.domain/string+) trigger a 404. Additionally, rather than redirecting to their long URL counterparts like they did before I implemented this fix, the short URL’s now just redirect to my website’s root ( I realize this is a comments thread and not a help area, but figured I’d give it ashot incase you or anyone else reading this can help or gain from the help you [hopefully] provide. Any ideas? Thanks!

Kevin – Are you sure you formatted your .htaccess file properly and put it in the root of your domain?

In order to have the stats working you have to replace the

line 269 ($statlink = $shorturl.’+’;)


$statlink = YOURLS_SITE .’/’.$keyword .’+’;

Hope this helps.

Great post thanks a lot.


[…] Source:… […]

I’ve had stats working without this change but I guess YMMV. All suggestions are good ones.

Hey Dave,

How do I set it so that when someone types in a url that in not in the database it is redirected back to the main domain.

Example: is not one of my short urls, but when I go to that domain, it is redirected back to

Is something like this possible? Thanks for the help!

Hi All

I tried to put my yourls files into a subdirectory on my website and followed all the instructions but I kept getting an error trying to view the admin page. In the end I put the files back into the root folder which works but I will be moving my files to another host and the control panel for that host happens to use /admin so I don’t think I can use it for yourls.

All I want to do is change the admin folder to /s but when I log into the main page and then click Admin Interface it still wants to go to mysite/admin. Is there a simple fix for this.

Hello again

Have just tried again. reinstalled yourls. followed the instructions but I get the error

Parse error: syntax error, unexpected ‘;’ in /home/a6300233/public_html/s2/includes/functions.php on line 98

Indeed, very useful and interesting writing. Thank you 😀
I recently wrote about Displaying Advertisements before redirection in Yourls. You should read it. 🙂
Thanks! Happy New Year

Hi Dave,

Thanks very much for your work! I have it installed and it’s working fine except for two problems I’ve seen, maybe related and one problem?

1) Non-existent pages give a
Forbidden (But the title says 403 Forbidden)
You don’t have permission to access /y/ on this server.

(/y/ is the subdirectory where yourls is installed)

2) Stats are not working and gives:
Not Found (Title says 404 Not Found)
The requested URL /pdc+ was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

( is one of my yourl shorties, so URL /pdc+ is the attempted shorty stats link

I saw a correction for this above, but I think functions.php has changed since it was written and I can’t locate what it refers to.

Thanks again!

The stats are not working, because of an error in the .htaccess mod rewrite. This is the correct rewrite:


RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9A-Za-z]+)/?$ /yourls/yourls-go.php?id=$1 [L]
RewriteRule ^([0-9A-Za-z]+)\+/?$ /yourls/yourls-infos.php?id=$1 [L]
RewriteRule ^([0-9A-Za-z]+)+all/?$ /yourls/yourls-infos.php?id=$1&all=1 [L]


Thank you so much for this writeup Dave, I really appreciate it. This is exactly what I’m wanting to do as well.

One question – Is this something I can implement if I have wordpress installed at my root domain? I’ve got yourls installed in a subfolder, and I want shortened URLs to point to the root domain as you’ve described, but I’m thinking that maybe this isn’t possible with an application like wordpress at the root as the FAQ on says,
“You cannot install YOURLS and, say, WordPress, in the same directory. Both need to handle URLs differently and need their own .htaccess file.”

I haven’t tested this with WordPress in the root directory but I would imagine there would be problems. Why not give it a try and see what happens? Please let me know your results.

Leave a comment