== Configuration Jekyll allows you to configure your sites in any way you can dream up, and it’s thanks to the powerful and flexible configuration options that this is possible. These options can either be specified in a `_config.yml` file placed in your site’s root directory, or can be specified as flags for the `jekyll` executable on command-line. === Global Configuration The table below lists the available settings for Jekyll, and the various `options` (specified in the configuration file) and `flags` (specified on the command-line) that control them. [width="100%", cols="6,6", options="header", role="table-responsive mt-3"] |======================================================================= |Setting |Options and Flags a| *Site Source* Change the directory where Jekyll will read files a| `source: DIR` `-s, --source DIR` a| *Site Destination* Change the directory where Jekyll will write files a| `destination: DIR` `-d, --destination DIR` a| *Safe* Disable custom plugins, and ignore symbolic links. a| `safe: BOOL` `--safe` a| *Exclude* Exclude directories and/or files from the conversion. These exclusions are relative to the site's source directory and cannot be outside the source directory. |`exclude: [DIR, FILE, ...]` a| *Include* Force inclusion of directories and/or files in the conversion. `.htaccess` is a good example since dotfiles are excluded by default. |`include: [DIR, FILE, ...]` a| *Keep files* When clobbering the site destination, keep the selected files. Useful for files that are not generated by jekyll; e.g. files or assets that are generated by your build tool. The paths are relative to the `destination`. |`keep_files: [DIR, FILE, ...]` a| *Time Zone* Set the time zone for site generation. This sets the `TZ` environment variable, which Ruby uses to handle time and date creation and manipulation. Any entry from the https://en.wikipedia.org/wiki/Tz_database[IANA Time Zone Database] is valid, e.g. `America/New_York`. A list of all available values can be found https://en.wikipedia.org/wiki/List_of_tz_database_time_zones[here]. The default is the local time zone, as set by your operating system. |`timezone: TIMEZONE` a| *Encoding* Set the encoding of files by name (only available for Ruby 1.9 or later). The default value is `utf-8` starting in 2.0.0, and `nil` before 2.0.0, which will yield the Ruby default of `ASCII-8BIT`. Available encodings can be shown by the command `ruby -e 'puts Encoding::list.join("\n")'`. |`encoding: ENCODING` a| *Defaults* Set defaults for YAML Front Matter variables. |see below |======================================================================= [WARNING] ==== Destination folders are cleaned on site builds. The contents of `` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `` configuration directive. Do not use an important location for `` instead, use it as a staging area and copy files from there to your web server. ==== === Build Command Options [width="100%", cols="6,6", options="header", role="table-responsive mt-3"] |======================================================================= |Setting |Options and Flags a| *Regeneration* Enable auto-regeneration of the site when files are modified. |`-w, --[no-]watch` a| *Configuration* Specify config files instead of using `_config.yml` automatically. Settings in later files override settings in earlier files. |`--config FILE1[,FILE2,...]` a| *Drafts* Process and render draft posts. a| `show_drafts: BOOL` `--drafts` a| *Environment* Use a specific environment value in the build. |`JEKYLL_ENV=production` a| *Future* Publish posts or collection documents with a future date. a| `future: BOOL` `--future` a| *LSI* Produce an index for related posts. a| `lsi: BOOL` `--lsi` a| *Limit Posts* Limit the number of posts to parse and publish. a| `limit_posts: NUM` `--limit_posts NUM` a| *Force polling* Force watch to use polling. |`--force_polling` a| *Verbose output* Print verbose output. |`-V, --verbose` a| *Silence Output* Silence the normal output from Jekyll during a build |`-q, --quiet` a| *Incremental build* Enable the experimental incremental build feature. Incremental build only re-builds posts and pages that have changed, resulting in significant performance improvements for large sites, but may also break site generation in certain cases. a| `incremental: BOOL` `-I, --incremental` a| *Liquid profiler* Generate a Liquid rendering profile to help you identify performance bottlenecks. a| `profile: BOOL` `--profile` |======================================================================= === Serve Command Options In addition to the options below, the `serve` sub-command can accept any of the options for the `build` sub-command, which are then applied to the site build which occurs right before your site is served. [width="100%", cols="6,6", options="header", role="table-responsive mt-3"] |====================================================================== |Setting |Options and Flags a| *Local Server Port* Listen on the given port. a| `port: PORT` `--port PORT` a| *Local Server Hostname* Listen at the given hostname. a| `host: HOSTNAME` `--host HOSTNAME` a| *Base URL* Serve the website from the given base URL a| `baseurl: URL` `--baseurl URL` a| *Detach* Detach the server from the terminal a| `detach: BOOL` `-B, --detach` a| *Skips the initial site build.* Skips the initial site build which occurs before the server is started. |`--skip-initial-build` a| *X.509 (SSL) Private Key* SSL Private Key. |`--ssl-key` a| *X.509 (SSL) Certificate* SSL Public certificate. |`--ssl-cert` |====================================================================== [WARNING] ==== Do not use tabs in configuration files. This will either lead to parsing errors, or Jekyll will revert to the default settings. Use spaces instead. ==== === Custom WEBrick Headers The Jekyll `serve` command enables an internal Web server - `WEBrick` - to serve your site without the need of an external Webserver (like Apache or Nginx). To control the internal server, you can provide custom headers for your site by adding them to `_config.yml` [source, yaml] -------------- # File: _config.yml webrick: headers: My-Header: My-Value My-Other-Header: My-Other-Value -------------- NOTE: Jekyll provide by default `Content-Type` and `Cache-Control` response headers: one *dynamic* in order to specify the nature of the data being served, the other *static* in order to disable caching so that you don't have to fight with Chrome's aggressive *caching* when you are in *development mode*. == Jekyll Environment === Folder structure Jekyll is, at its core, a text transformation engine. The concept behind the system is this: you give it text written in your favorite markup language, be that Markdown, Textile, or just plain HTML, and it churns that through a layout or a series of layout files. Throughout that process you can tweak how you want the site URLs to look, what data gets displayed in the layout, and more. This is all done through editing text files; the static web site is the final product. A basic Jekyll site usually looks something like this: [source, sh] ---- . ├── _config.yml ├── _drafts | ├── begin-with-the-crazy-ideas.textile | └── on-simplicity-in-technology.markdown ├── _includes | ├── footer.html | └── header.html ├── _layouts | ├── default.html | └── post.html ├── _posts | ├── 2007-10-29-why-every-programmer-should-play-nethack.textile | └── 2009-04-26-barcamp-boston-4-roundup.textile ├── _data | └── members.yml ├── _site ├── .jekyll-metadata └── index.html ---- === Dirs and Files An overview of what each of these does: [width="100%", cols="6,6", options="header", role="table-responsive mt-3"] |======================================================================= |File / Directory |Description |`_config.yml` |Stores configuration data. Many of these options can be specified from the command line executable but it's easier to specify them here so you don't have to remember them. |`_drafts` |Drafts are unpublished posts. The format of these files is without a date: `title.MARKUP`. Learn how to work with drafts. |`_includes` |These are the partials that can be mixed and matched by your layouts and posts to facilitate reuse. The liquid tag `{% include file.ext %}` can be used to include the partial in `_includes/file.ext`. |`_layouts` |These are the templates that wrap posts. Layouts are chosen on a post-by-post basis in the YAML Front Matter, which is described in the next section. The liquid tag `{{ content }}` is used to inject content into the web page. |`_posts` |Your dynamic content, so to speak. The naming convention of these files is important, and must follow the format: `YEAR-MONTH-DAY-title.MARKUP`. The permalinks can be customized for each post, but the date and markup language are determined solely by the file name. |`_data` |Well-formatted site data should be placed here. The Jekyll engine will autoload all YAML files in this directory (using either the `.yml`, `.yaml`, `.json` or `.csv` formats and extensions) and they will be accessible via `site.data`. If there's a file `members.yml` under the directory, then you can access contents of the file through `site.data.members`. |`_site` |This is where the generated site will be placed (by default) once Jekyll is done transforming it. It's probably a good idea to add this to your `.gitignore` file. |`.jekyll-metadata` |This helps Jekyll keep track of which files have not been modified since the site was last built, and which files will need to be regenerated on the next build. This file will not be included in the generated site. It's probably a good idea to add this to your `.gitignore` file. |`index.html` and other HTML, Markdown, Textile files |Provided that the file has a YAML Front Matter section, it will be transformed by Jekyll. The same will happen for any `.html`, `.markdown`, `.md`, or `.textile` file in your site's root directory or directories not listed above. |Other Files/Folders |Every other directory and file except for those listed above such as `css` and `images` folders, `favicon.ico` files, and so forthÔÇöwill be copied verbatim to the generated site. There are plenty of sites already using Jekyll if you're curious to see how they're laid out. |======================================================================= === Set a Jekyll environment You can specify a Jekyll environment at build time. In the build (or serve) arguments, you can specify a Jekyll environment and value. The build will then apply this value in any conditional statements in your content. For example, suppose you set this conditional statement in your code: [source, liquid] -------------- {% raw %} {% if jekyll.environment === "production" %} {% include disqus.html %} {% endif %} {% endraw %} -------------- When you build your Jekyll site, the content inside the `if` statement won't be run unless you also specify a `production` environment in the build command, like this: [source, sh] -------------- JEKYLL_ENV=production jekyll build -------------- Specifying an environment value allows you to make certain content available only within specific environments. The default value for `JEKYLL_ENV` is `development`. Therefore if you omit `JEKYLL_ENV` from the build arguments, the default value will be `JEKYLL_ENV=development`. Any content inside [source, liquid] -------------- {% if jekyll.environment == "development" %} -------------- tags will automatically appear in the build. Your environment values can be anything you want (not just `development` or `production`). Some elements you might want to hide in development environments include Disqus comment forms or Google Analytics. Conversely, you might want to expose an "Edit me in GitHub" button in a development environment but not include it in production environments. By specifying the option in the build command, you avoid having to change values in your configuration files when moving from one environment to another. === Front Matter defaults Using YAML Front Matter is one way that you can specify configuration in the pages and posts for your site. Setting things like a default layout, or customizing the title, or specifying a more precise date/time for the post can all be added to your page or post front matter. Often times, you will find that you are repeating a lot of configuration options. Setting the same layout in each file, adding the same category - or categories - to a post, etc. You can even add custom variables like author names, which might be the same for the majority of posts on your blog. Instead of repeating this configuration each time you create a new post or page, Jekyll provides a way to set these defaults in the site configuration. To do this, you can specify site-wide defaults using the `defaults` key in the `_config.yml` file in your project's root directory. The `defaults` key holds an array of scope/values pairs that define what defaults should be set for a particular file path, and optionally, a file type in that path. Let's say that you want to add a default layout to all pages and posts in your site. You would add this to your `_config.yml` file: [source, yaml] -------------- defaults: - scope: path: "" # an empty string here means all files in the project values: layout: "default" -------------- [NOTE] ==== Please stop and rerun `jekyll serve` command. The `_config.yml` master configuration file contains global configurations and variable definitions that are read once at execution time. Changes made to `_config.yml` during automatic regeneration are not loaded until the next execution. Note `Data Files` are included and reloaded during automatic regeneration. ==== Here, we are scoping the `values` to any file that exists in the path `scope`. Since the path is set as an empty string, it will apply to **all files** in your project. You probably don't want to set a layout on every file in your project - like css files, for example - so you can also specify a `type` value under the `scope` key. [source, yaml] -------------- defaults: - scope: path: "" # an empty string here means all files in the project type: "posts" # previously `post` in Jekyll 2.2. values: layout: "default" -------------- Now, this will only set the layout for files where the type is `posts`. The different types that are available to you are `pages`, `posts`, `drafts` or any collection in your site. While `type` is optional, you must specify a value for `path` when creating a `scope|values` pair. As mentioned earlier, you can set multiple scope/values pairs for `defaults`. [source, yaml] -------------- defaults: - scope: path: "" type: "posts" values: layout: "my-site" - scope: path: "projects" type: "pages" # previously `page` in Jekyll 2.2. values: layout: "project" # overrides previous default layout author: "Mr. Hyde" -------------- With these defaults, all posts would use the `my-site` layout. Any html files that exist in the `projects/` folder will use the `project` layout, if it exists. Those files will also have the `page.author` liquid variable set to `Mr. Hyde`. [source, yaml] -------------- collections: - my_collection: output: true defaults: - scope: path: "" type: "my_collection" # a collection in your site, in plural form values: layout: "default" -------------- In this example, the `layout` is set to `default` inside the collection with the name `my_collection`. ==== Precedence Jekyll will apply all of the configuration settings you specify in the `defaults` section of your `_config.yml` file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope. You can see that in the second to last example above. First, we set the default layout to `my-site`. Then, using a more specific path, we set the default layout for files in the `projects/` path to `project`. This can be done with any value that you would set in the page or post front matter. Finally, if you set defaults in the site configuration by adding a `defaults` section to your `_config.yml` file, you can override those settings in a post or page file. All you need to do is specify the settings in the post or page front matter. For example: [source, yaml] -------------- # In _config.yml ... defaults: - scope: path: "projects" type: "pages" values: layout: "project" author: "Mr. Hyde" category: "project" ... -------------- [source, yaml] -------------- # In projects/foo_project.md --- author: "John Smith" layout: "foobar" --- The post text goes here... -------------- The `projects/foo_project.md` would have the `layout` set to `foobar` instead of `project` and the `author` set to `John Smith` instead of `Mr. Hyde` when the site is built. === Default Configuration Jekyll runs with the following configuration options by default. Alternative settings for these options can be explicitly specified in the configuration file or on the command-line. [WARNING] ==== There are two unsupported kramdown options. Please note that both `remove_block_html_tags` and `remove_span_html_tags` are currently *unsupported* in Jekyll due to the fact that they are not included within the kramdown HTML converter. ==== [source, yaml] -------------- # Where things are # source: . destination: ./_site plugins_dir: _plugins layouts_dir: _layouts data_dir: _data includes_dir: _includes collections: posts: output: true # Handling Reading # safe: false include: [".htaccess"] exclude: [] keep_files: [".git", ".svn"] encoding: "utf-8" markdown_ext: "markdown,mkdown,mkdn,mkd,md" # Filtering Content # show_drafts: null limit_posts: 0 future: false unpublished: false # Plugins # whitelist: [] gems: [] # Conversion # markdown: kramdown highlighter: rouge lsi: false excerpt_separator: "\n\n" incremental: false # Serving # detach: false port: 4000 host: 127.0.0.1 baseurl: "" # does not include hostname show_dir_listing: false # Outputting # permalink: date paginate_path: /page:num timezone: null quiet: false verbose: false defaults: [] liquid: error_mode: warn # Markdown Processors # rdiscount: extensions: [] redcarpet: extensions: [] kramdown: auto_ids: true footnote_nr: 1 entity_output: as_char toc_levels: 1..6 smart_quotes: lsquo,rsquo,ldquo,rdquo input: GFM hard_wrap: false footnote_nr: 1 -------------- === Liquid Options Liquid's response to errors can be configured by setting `error_mode`. The options are - `lax` --- Ignore all errors. - `warn` --- Output a warning on the console for each error. - `strict` --- Output an error message and stop the build. === Markdown Options The various Markdown renderers supported by Jekyll sometimes have extra options available. ==== Redcarpet Redcarpet can be configured by providing an `extensions` sub-setting, whose value should be an array of strings. Each string should be the name of one of the `Redcarpet::Markdown` class's extensions; if present in the array, it will set the corresponding extension to `true`. Jekyll handles two special Redcarpet extensions: - `no_fenced_code_blocks` --- By default, Jekyll sets the `fenced_code_blocks` extension (for delimiting code blocks with triple tildes or triple backticks) to `true`, probably because GitHub's eager adoption of them is starting to make them inescapable. Redcarpet's normal `fenced_code_blocks` extension is inert when used with Jekyll; instead, you can use this inverted version of the extension for disabling fenced code. Note that you can also specify a language for highlighting after the first delimiter: [source, ruby] -------------- # ...ruby code -------------- With both fenced code blocks and highlighter enabled, this will statically highlight the code; without any syntax highlighter, it will add a `class="LANGUAGE"` attribute to the `` element, which can be used as a hint by various JavaScript code highlighting libraries. - `smart` --- This pseudo-extension turns on SmartyPants, which converts straight quotes to curly quotes and runs of hyphens to em (`---`) and en (`--`) dashes. All other extensions retain their usual names from Redcarpet, and no renderer options aside from `smart` can be specified in Jekyll. [A list of available extensions can be found in the Redcarpet README file.][redcarpet_extensions] Make sure you're looking at the README for the right version of Redcarpet: Jekyll currently uses v3.2.x. The most commonly used extensions are: - `tables` - `no_intra_emphasis` - `autolink` [redcarpet_extensions]: https://github.com/vmg/redcarpet/blob/v3.2.2/README.markdown#and-its-like-really-simple-to-use ### Custom Markdown Processors If you're interested in creating a custom markdown processor, you're in luck! Create a new class in the `Jekyll::Converters::Markdown` namespace: [source, ruby] -------------- class Jekyll::Converters::Markdown::MyCustomProcessor def initialize(config) require 'funky_markdown' @config = config rescue LoadError STDERR.puts 'You are missing a library required for Markdown. Please run:' STDERR.puts ' $ [sudo] gem install funky_markdown' raise FatalException.new("Missing dependency: funky_markdown") end def convert(content) ::FunkyMarkdown.new(content).convert end end -------------- Once you've created your class and have it properly set up either as a plugin in the `_plugins` folder or as a gem, specify it in your `_config.yml`: [source, yaml] -------------- markdown: MyCustomProcessor -------------- === Incremental Regeneration Incremental regeneration helps shorten build times by only generating documents and pages that were updated since the previous build. It does this by keeping track of both file modification times and inter-document dependencies in the `.jekyll-metadata` file. [WARNING] ==== Incremental regeneration is still an experimental feature. While incremental regeneration will work for the most common cases, it will not work correctly in every scenario. Please be extremely cautious when using the feature, and report any problems not listed below by {uri-jekyll-submit-issue}[opening an issue on GitHub]. ==== Under the current implementation, incremental regeneration will only generate a document or page if either it, or one of its dependencies, is modified. Currently, the only types of dependencies tracked are includes (using the `{% include %}` tag) and layouts. This means that plain references to other documents (for example, the common case of iterating over `site.posts` in a post listings page) will not be detected as a dependency. To remedy some of these shortfalls, putting `regenerate: true` in the front-matter of a document will force Jekyll to regenerate it regardless of whether it has been modified. Note that this will generate the specified document only; references to other documents' contents will not work since they won't be re-rendered. Incremental regeneration can be enabled via the `--incremental` flag (`-i` for short) from the command-line or by setting `incremental: true` in your configuration file.