HUGO
Menu
GitHub 90265 stars Mastodon

Configure output formats

Configure output formats.

An output format is a collection of settings that defines how Hugo renders a file when building a site. For example, html, json, and rss are built-in output formats. You can create multiple output formats and control their generation based on page kind, or by enabling one or more output formats for specific pages.

You can output a page in as many formats as you want. Define any number of output formats, provided each resolves to a unique file system path.

This is the default output format configuration in tabular form:

typemediaTypeweightbaseNameisHTMLisPlainTextnoUglynotAlternativepathpermalinkableprotocolrelrootugly
404text/html0truefalsefalsetruetruefalsetrue
aliastext/html0truefalsefalsefalsefalsefalsetrue
amptext/html0indextruefalsefalsefalseamptrueamphtmlfalsefalse
calendartext/calendar0indexfalsetruefalsefalsefalsewebcal://alternatefalsefalse
csstext/css0stylesfalsetruefalsetruefalsestylesheetfalsefalse
csvtext/csv0indexfalsetruefalsefalsefalsealternatefalsefalse
gotmpltext/x-gotmpl0falsetruefalsetruefalsefalsefalse
htmltext/html10indextruefalsefalsefalsetruecanonicalfalsefalse
jsonapplication/json0indexfalsetruefalsefalsefalsealternatefalsefalse
markdowntext/markdown0indexfalsetruefalsefalsefalsealternatefalsefalse
robotstext/plain0robotsfalsetruefalsefalsefalsealternatetruefalse
rssapplication/rss+xml0indexfalsefalsetruefalsefalsealternatefalsefalse
sitemapapplication/xml0sitemapfalsefalsefalsefalsefalsesitemapfalsetrue
sitemapindexapplication/xml0sitemapfalsefalsefalsefalsefalsesitemaptruetrue
webappmanifestapplication/manifest+json0manifestfalsetruefalsetruefalsemanifestfalsefalse

Default configuration

This is the default configuration that matches the table above:

outputFormats:
  '404':
    baseName: ''
    isHTML: true
    isPlainText: false
    mediaType: text/html
    noUgly: false
    notAlternative: true
    path: ''
    permalinkable: true
    protocol: ''
    rel: ''
    root: false
    ugly: true
    weight: 0
  alias:
    baseName: ''
    isHTML: true
    isPlainText: false
    mediaType: text/html
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: ''
    root: false
    ugly: true
    weight: 0
  amp:
    baseName: index
    isHTML: true
    isPlainText: false
    mediaType: text/html
    noUgly: false
    notAlternative: false
    path: amp
    permalinkable: true
    protocol: ''
    rel: amphtml
    root: false
    ugly: false
    weight: 0
  calendar:
    baseName: index
    isHTML: false
    isPlainText: true
    mediaType: text/calendar
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: webcal://
    rel: alternate
    root: false
    ugly: false
    weight: 0
  css:
    baseName: styles
    isHTML: false
    isPlainText: true
    mediaType: text/css
    noUgly: false
    notAlternative: true
    path: ''
    permalinkable: false
    protocol: ''
    rel: stylesheet
    root: false
    ugly: false
    weight: 0
  csv:
    baseName: index
    isHTML: false
    isPlainText: true
    mediaType: text/csv
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: alternate
    root: false
    ugly: false
    weight: 0
  gotmpl:
    baseName: ''
    isHTML: false
    isPlainText: true
    mediaType: text/x-gotmpl
    noUgly: false
    notAlternative: true
    path: ''
    permalinkable: false
    protocol: ''
    rel: ''
    root: false
    ugly: false
    weight: 0
  html:
    baseName: index
    isHTML: true
    isPlainText: false
    mediaType: text/html
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: true
    protocol: ''
    rel: canonical
    root: false
    ugly: false
    weight: 10
  json:
    baseName: index
    isHTML: false
    isPlainText: true
    mediaType: application/json
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: alternate
    root: false
    ugly: false
    weight: 0
  markdown:
    baseName: index
    isHTML: false
    isPlainText: true
    mediaType: text/markdown
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: alternate
    root: false
    ugly: false
    weight: 0
  robots:
    baseName: robots
    isHTML: false
    isPlainText: true
    mediaType: text/plain
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: alternate
    root: true
    ugly: false
    weight: 0
  rss:
    baseName: index
    isHTML: false
    isPlainText: false
    mediaType: application/rss+xml
    noUgly: true
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: alternate
    root: false
    ugly: false
    weight: 0
  sitemap:
    baseName: sitemap
    isHTML: false
    isPlainText: false
    mediaType: application/xml
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: sitemap
    root: false
    ugly: true
    weight: 0
  sitemapindex:
    baseName: sitemap
    isHTML: false
    isPlainText: false
    mediaType: application/xml
    noUgly: false
    notAlternative: false
    path: ''
    permalinkable: false
    protocol: ''
    rel: sitemap
    root: true
    ugly: true
    weight: 0
  webappmanifest:
    baseName: manifest
    isHTML: false
    isPlainText: true
    mediaType: application/manifest+json
    noUgly: false
    notAlternative: true
    path: ''
    permalinkable: false
    protocol: ''
    rel: manifest
    root: false
    ugly: false
    weight: 0
[outputFormats]
  [outputFormats.404]
    baseName = ''
    isHTML = true
    isPlainText = false
    mediaType = 'text/html'
    noUgly = false
    notAlternative = true
    path = ''
    permalinkable = true
    protocol = ''
    rel = ''
    root = false
    ugly = true
    weight = 0
  [outputFormats.alias]
    baseName = ''
    isHTML = true
    isPlainText = false
    mediaType = 'text/html'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = ''
    root = false
    ugly = true
    weight = 0
  [outputFormats.amp]
    baseName = 'index'
    isHTML = true
    isPlainText = false
    mediaType = 'text/html'
    noUgly = false
    notAlternative = false
    path = 'amp'
    permalinkable = true
    protocol = ''
    rel = 'amphtml'
    root = false
    ugly = false
    weight = 0
  [outputFormats.calendar]
    baseName = 'index'
    isHTML = false
    isPlainText = true
    mediaType = 'text/calendar'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = 'webcal://'
    rel = 'alternate'
    root = false
    ugly = false
    weight = 0
  [outputFormats.css]
    baseName = 'styles'
    isHTML = false
    isPlainText = true
    mediaType = 'text/css'
    noUgly = false
    notAlternative = true
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'stylesheet'
    root = false
    ugly = false
    weight = 0
  [outputFormats.csv]
    baseName = 'index'
    isHTML = false
    isPlainText = true
    mediaType = 'text/csv'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'alternate'
    root = false
    ugly = false
    weight = 0
  [outputFormats.gotmpl]
    baseName = ''
    isHTML = false
    isPlainText = true
    mediaType = 'text/x-gotmpl'
    noUgly = false
    notAlternative = true
    path = ''
    permalinkable = false
    protocol = ''
    rel = ''
    root = false
    ugly = false
    weight = 0
  [outputFormats.html]
    baseName = 'index'
    isHTML = true
    isPlainText = false
    mediaType = 'text/html'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = true
    protocol = ''
    rel = 'canonical'
    root = false
    ugly = false
    weight = 10
  [outputFormats.json]
    baseName = 'index'
    isHTML = false
    isPlainText = true
    mediaType = 'application/json'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'alternate'
    root = false
    ugly = false
    weight = 0
  [outputFormats.markdown]
    baseName = 'index'
    isHTML = false
    isPlainText = true
    mediaType = 'text/markdown'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'alternate'
    root = false
    ugly = false
    weight = 0
  [outputFormats.robots]
    baseName = 'robots'
    isHTML = false
    isPlainText = true
    mediaType = 'text/plain'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'alternate'
    root = true
    ugly = false
    weight = 0
  [outputFormats.rss]
    baseName = 'index'
    isHTML = false
    isPlainText = false
    mediaType = 'application/rss+xml'
    noUgly = true
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'alternate'
    root = false
    ugly = false
    weight = 0
  [outputFormats.sitemap]
    baseName = 'sitemap'
    isHTML = false
    isPlainText = false
    mediaType = 'application/xml'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'sitemap'
    root = false
    ugly = true
    weight = 0
  [outputFormats.sitemapindex]
    baseName = 'sitemap'
    isHTML = false
    isPlainText = false
    mediaType = 'application/xml'
    noUgly = false
    notAlternative = false
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'sitemap'
    root = true
    ugly = true
    weight = 0
  [outputFormats.webappmanifest]
    baseName = 'manifest'
    isHTML = false
    isPlainText = true
    mediaType = 'application/manifest+json'
    noUgly = false
    notAlternative = true
    path = ''
    permalinkable = false
    protocol = ''
    rel = 'manifest'
    root = false
    ugly = false
    weight = 0
{
   "outputFormats": {
      "404": {
         "baseName": "",
         "isHTML": true,
         "isPlainText": false,
         "mediaType": "text/html",
         "noUgly": false,
         "notAlternative": true,
         "path": "",
         "permalinkable": true,
         "protocol": "",
         "rel": "",
         "root": false,
         "ugly": true,
         "weight": 0
      },
      "alias": {
         "baseName": "",
         "isHTML": true,
         "isPlainText": false,
         "mediaType": "text/html",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "",
         "root": false,
         "ugly": true,
         "weight": 0
      },
      "amp": {
         "baseName": "index",
         "isHTML": true,
         "isPlainText": false,
         "mediaType": "text/html",
         "noUgly": false,
         "notAlternative": false,
         "path": "amp",
         "permalinkable": true,
         "protocol": "",
         "rel": "amphtml",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "calendar": {
         "baseName": "index",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/calendar",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "webcal://",
         "rel": "alternate",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "css": {
         "baseName": "styles",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/css",
         "noUgly": false,
         "notAlternative": true,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "stylesheet",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "csv": {
         "baseName": "index",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/csv",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "alternate",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "gotmpl": {
         "baseName": "",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/x-gotmpl",
         "noUgly": false,
         "notAlternative": true,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "html": {
         "baseName": "index",
         "isHTML": true,
         "isPlainText": false,
         "mediaType": "text/html",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": true,
         "protocol": "",
         "rel": "canonical",
         "root": false,
         "ugly": false,
         "weight": 10
      },
      "json": {
         "baseName": "index",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "application/json",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "alternate",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "markdown": {
         "baseName": "index",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/markdown",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "alternate",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "robots": {
         "baseName": "robots",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "text/plain",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "alternate",
         "root": true,
         "ugly": false,
         "weight": 0
      },
      "rss": {
         "baseName": "index",
         "isHTML": false,
         "isPlainText": false,
         "mediaType": "application/rss+xml",
         "noUgly": true,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "alternate",
         "root": false,
         "ugly": false,
         "weight": 0
      },
      "sitemap": {
         "baseName": "sitemap",
         "isHTML": false,
         "isPlainText": false,
         "mediaType": "application/xml",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "sitemap",
         "root": false,
         "ugly": true,
         "weight": 0
      },
      "sitemapindex": {
         "baseName": "sitemap",
         "isHTML": false,
         "isPlainText": false,
         "mediaType": "application/xml",
         "noUgly": false,
         "notAlternative": false,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "sitemap",
         "root": true,
         "ugly": true,
         "weight": 0
      },
      "webappmanifest": {
         "baseName": "manifest",
         "isHTML": false,
         "isPlainText": true,
         "mediaType": "application/manifest+json",
         "noUgly": false,
         "notAlternative": true,
         "path": "",
         "permalinkable": false,
         "protocol": "",
         "rel": "manifest",
         "root": false,
         "ugly": false,
         "weight": 0
      }
   }
}
baseName
(string) The base name of the published file. Default is index.
isHTML
(bool) Whether to classify the output format as HTML. This value determines when Hugo injects the LiveReload script and, together with permalinkable, whether Hugo generates alias redirects. Default is false.
isPlainText
(bool) Whether to treat the output of templates for this output format as plain text instead of HTML. Set this to true for output formats where HTML escaping would corrupt the output, such as JSON or CSV. Default is false. The table below shows how the setting affects templates.
Effectfalsetrue
How Hugo prints valuesHugo escapes values, so that the output is safe to use in HTML. For example, < becomes &lt;.Hugo prints values without escaping them.
Return type for partials.Include and partials.IncludeCachedtemplate.HTMLstring
Go package used to parse templateshtml/templatetext/template

To print a value from a trusted source without escaping it, declare it safe. See safe types for details.

mediaType
(string) The media type of the published file. This must match one of the configured media types.
notAlternative
(bool) Whether to exclude this output format from the values returned by the AlternativeOutputFormats method on a Page object. Default is false.
noUgly
(bool) Whether to disable ugly URLs for this output format when uglyURLs are enabled in your project configuration. Default is false.
path
(string) The first segment of the publication path for this output format. This path segment is relative to the root of your public directory. If omitted, Hugo uses the file’s original content path for publishing.
permalinkable
(bool) Whether to return the rendering output format rather than the main output format when invoking the Permalink and RelPermalink methods on a Page object. Along with isHTML, this must be true to create alias redirects. Default is false, except for the html, amp, and 404 output formats, where the default is true.
protocol
(string) The protocol (scheme) of the URL for this output format. For example, https:// or webcal://. Default is the scheme of the baseURL parameter in your project configuration, typically https://.
rel
(string) The relationship of the output format to the current page. Hugo uses this property to determine the canonical output format of the current page. For the predefined html output format, the default value is canonical. For all other predefined output formats, the default value is alternate.
root
(bool) Whether to publish files to the root of the public directory. Default is false.
ugly
(bool) Whether to enable ugly URLs for this output format when uglyURLs is false in your project configuration. Default is false.
weight
(int) When set to a non-zero value, Hugo uses the weight as the first criterion when sorting output formats, falling back to the name of the output format. Lighter items float to the top, while heavier items sink to the bottom. Hugo renders output formats sequentially based on the sort order. Default is 0, except for the html output format, which has a default weight of 10.

Modify an output format

You can modify any of the default output formats. For example, adjust the weight to render json before html when Hugo generates both:

outputFormats:
  html:
    weight: 2
  json:
    weight: 1
[outputFormats]
  [outputFormats.html]
    weight = 2
  [outputFormats.json]
    weight = 1
{
   "outputFormats": {
      "html": {
         "weight": 2
      },
      "json": {
         "weight": 1
      }
   }
}

When you modify a default output format, you only need to define the properties that differ from their default values.

Create an output format

You can create new output formats as needed. For example, follow these steps to create an output format for Atom feeds.

Step 1
Each output format requires a media type. Atom feeds use application/atom+xml, which is not one of the default media types, so create it first.
mediaTypes:
  application/atom+xml:
    suffixes:
    - atom
[mediaTypes]
  [mediaTypes.'application/atom+xml']
    suffixes = ['atom']
{
   "mediaTypes": {
      "application/atom+xml": {
         "suffixes": [
            "atom"
         ]
      }
   }
}

See configure media types for more information.

Step 2
Create a new output format:
outputFormats:
  atom:
    mediaType: application/atom+xml
    noUgly: true
[outputFormats]
  [outputFormats.atom]
    mediaType = 'application/atom+xml'
    noUgly = true
{
   "outputFormats": {
      "atom": {
         "mediaType": "application/atom+xml",
         "noUgly": true
      }
   }
}

The new output format uses the default settings for all other properties.

Step 3
Specify the page kinds for which to render this output format:
outputs:
  home:
  - html
  - rss
  - atom
  section:
  - html
  - rss
  - atom
  taxonomy:
  - html
  - rss
  - atom
  term:
  - html
  - rss
  - atom
[outputs]
  home = ['html', 'rss', 'atom']
  section = ['html', 'rss', 'atom']
  taxonomy = ['html', 'rss', 'atom']
  term = ['html', 'rss', 'atom']
{
   "outputs": {
      "home": [
         "html",
         "rss",
         "atom"
      ],
      "section": [
         "html",
         "rss",
         "atom"
      ],
      "taxonomy": [
         "html",
         "rss",
         "atom"
      ],
      "term": [
         "html",
         "rss",
         "atom"
      ]
   }
}

See configure outputs for more information.

Step 4
Create a template to render the output format. Atom feeds are lists, so create a list template. Use the template lookup order to find the correct template path:
layouts/list.atom.atom

Use the embedded RSS template as a model for your template.

List output formats

Each Page object provides two methods to access output formats. The OutputFormats method returns all output formats, including the current one, and the AlternativeOutputFormats method returns all output formats except the current one. For example, use the AlternativeOutputFormats method to create a link element for each alternative output format within the head element:

{{ range .AlternativeOutputFormats }}
  <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
{{ end }}

The URL returned by a Page object’s Permalink and RelPermalink methods depends on the current output format. For output formats with permalinkable set to true, such as html and amp, the methods return that format’s own URL. For all other output formats, the methods return the URL of the page’s primary output format.

For example, in a page.json.json template, these methods return these values:

{{ .RelPermalink }} → /that-page/
{{ with .OutputFormats.Get "json" }}
  {{ .RelPermalink }} → /that-page/index.json
{{ end }}

To make these methods return the URL of the current template’s output format, set permalinkable to true for that format.

With permalinkable set to true for the json output format, in the same page.json.json template, these methods return these values:

{{ .RelPermalink }} → /that-page/index.json
{{ with .OutputFormats.Get "html" }}
  {{ .RelPermalink }} → /that-page/
{{ end }}

Template lookup order

Each output format requires a template conforming to the template lookup order.

For the highest specificity in the template lookup order, include the page kind, output format, and suffix in the file name:

[page kind].[output format].[suffix]

For example, the table below shows the template path for section pages in each of three output formats.

Output formatTemplate path
htmllayouts/section.html.html
jsonlayouts/section.json.json
rsslayouts/section.rss.xml