Site.url defaults to localhost when not in production environment


Since 3.3.0 (PR 5431) site.url translates “” to “localhost” when not in production environment.

The relevant code from lib/jekyll/commands/serve.rb:

def default_url(opts)
  config = configuration_from_options(opts)
    config["ssl_cert"] && config["ssl_key"],
    config["host"] == "" ? "localhost" : config["host"],

This breaks current Chrome and perhaps others running under windows. There are workarounds but these are clumsy and do not work well under windows 7+. Unfortunately for a current project I must work in the windows world both as a developer and as a user of the site…

Thus two questions:

What problem(s) does this translation solve?
Would it not be better to change to:

def default_url(opts)
  config = configuration_from_options(opts)
    config["ssl_cert"] && config["ssl_key"],
    config["host"]=="" ? "localhost" : config["host"],

This would allow the developer to specify the url as ‘’ or by leaving the specification empty default to ‘localhost’. My task would be easier. The site user would find a functional site when using Chrome on a windows box.

Since this is not necessarily a bug and I am new to the Jekyll ecosystem I chose to ask the question here. If others think this idea has merit I can turn it into a pull request.


How does it break Chrome on Windows?
I’m able to access http://localhost:4000 without issues on my Chrome for Windows


Same here. or http://localhost:4000 both bring up the development server just fine for me on Windows 7.


Perhaps “break” is too strong. Entering “http://localhost:4000” in the address bar never resolves and never opens the site. “” immediately opens the site. (I am on Chrome “Version 61.0.3163.100 (Official Build) (64-bit)” ). This becomes an issue using Formspree for contact messages from my users. After Formspree receives the message the user is redirected to a page within my site. In development the redirect is to “http://localhost:4000”. Sadly in Chrome that leaves the user watching the browser fail to open any page since “localhost” is not resolved. I do have a workaround that involves an oddball entry in hosts for url resolution.


# These do not work:
url: ""
url: ""
url: "http://localhost:4000" # the base hostname & protocol for your site

# This as part of my workaround does function:
# development
baseurl: ""

# production
baseurl: "/bugger" 
url: "" 

The contact form:

<form action=""
<!-- In development -->
    <input type="text" name="_next" value={{ http://loco:4000 }} />
<!-- In Production -->
    <input type="text" name="_next" value={{ site.baseurl | absolute }} />

I am currently using Win7.
The hosts file:

# localhost name resolution is handled within DNS itself.
# localhost

# Tried each of these lines in turn: localhost localhost.

# The workaround involves:
# remove other lines & put this into hosts loco

This works in development. Then before pushing to github I must change the url.


so you are using jekyll serve on a server that the public is using? that is not what it is expecting you to do, it is expecting you to do jekyll build and then deploy the _site folder to a webserver.

I think you can get jekyll serve to do what it sounds like you want by passing in an environment variable - I think that if you set that to production then it will not swap out the site.url setting. Jekyll is changing it to localhost for development as it makes it easier under certain circumstances to do development without the real site.url value.


I m ay not be understanding your problem after re-reading your last reply.

Where are you hosting your site?

this part doesn’t make sense if you are hosting on GH.

Ah - maybe you are using GH pages but are pushing the _site folder? that may make sense if you do jekyll serve and then push that - if so you should be doing jekyll build and then push?


@ rdyar:
Am using github pages for the public facing version of the site. Development is done on my laptop and the laptop of another individual.

Your comment about pushing the _site folder to production caught my attention. That is in fact what I have been doing. But github pages generates its own _site folder when changes are pushed to the master branch on origin.

With that idea I was able to solve my problem. I removed that folder from the git origin of the project as well as the local clone. Then added _site to .gitignore.

I returned to the default windows hosts file.

In _config.yml in development

baseurl: "" # change to baseurl: "/bugger" in production
url: ""

in contact.html

<input type="text" name="_next" value={{ site.baseurl | absolute }} />



cool - glad you got it sorted.

are you using 2 config files? are you at some point changing baseurl back and forth?

jekyll is sort of doing this for you if you are doing this manually as of 3.3 - depending on how you build your urls.


Yes. Having proven to myself that this setup works I am using two config files:


baseurl: "/bugger"
url: ""

and _config_local.yml:

baseurl: ""
url: ""

Then in development:

jekyll serve --config _config.yml,_config_local.yml

I think github pages must, in effect, call:

jekyl serve --config _config.yml


if you use the newish url filters to build your links you no longer need to do that… the link above to the 3.3 release notes explains it though it is kind of confusing, it specifically addresses your situation where you have two configs in order to deal with the baseurl when doing local dev.


If the only difference between the two config files, is the baseurl, then you needn’t use two config files at all… Simply set baseurl: /bugger , then serve and preview your site at http://localhost:4000/bugger/