Configure permalinks
This is the default configuration:
permalinks:
page: {}
section: {}
taxonomy: {}
term: {}
[permalinks]
[permalinks.page]
[permalinks.section]
[permalinks.taxonomy]
[permalinks.term]
{
"permalinks": {
"page": {},
"section": {},
"taxonomy": {},
"term": {}
}
}
Define a URL pattern for each top-level section. Each URL pattern can target a given language and/or page kind.
The url front matter field overrides any matching permalink pattern.
Monolingual example
With this content structure:
content/
├── posts/
│ ├── bash-in-slow-motion.md
│ └── tls-in-a-nutshell.md
├── tutorials/
│ ├── git-for-beginners.md
│ └── javascript-bundling-with-hugo.md
└── _index.mdRender tutorials under “training”, and render the posts under “articles” with a date-base hierarchy:
permalinks:
page:
posts: /articles/:year/:month/:slug/
tutorials: /training/:slug/
section:
posts: /articles/
tutorials: /training/
[permalinks]
[permalinks.page]
posts = '/articles/:year/:month/:slug/'
tutorials = '/training/:slug/'
[permalinks.section]
posts = '/articles/'
tutorials = '/training/'
{
"permalinks": {
"page": {
"posts": "/articles/:year/:month/:slug/",
"tutorials": "/training/:slug/"
},
"section": {
"posts": "/articles/",
"tutorials": "/training/"
}
}
}
The structure of the published site will be:
public/
├── articles/
│ ├── 2023/
│ │ ├── 04/
│ │ │ └── bash-in-slow-motion/
│ │ │ └── index.html
│ │ └── 06/
│ │ └── tls-in-a-nutshell/
│ │ └── index.html
│ └── index.html
├── training/
│ ├── git-for-beginners/
│ │ └── index.html
│ ├── javascript-bundling-with-hugo/
│ │ └── index.html
│ └── index.html
└── index.htmlTo create a date-based hierarchy for regular pages in the content root:
permalinks:
page:
/: /:year/:month/:slug/
[permalinks]
[permalinks.page]
'/' = '/:year/:month/:slug/'
{
"permalinks": {
"page": {
"/": "/:year/:month/:slug/"
}
}
}
Use the same approach with taxonomy terms. For example, to omit the taxonomy segment of the URL:
permalinks:
term:
tags: /:slug/
[permalinks]
[permalinks.term]
tags = '/:slug/'
{
"permalinks": {
"term": {
"tags": "/:slug/"
}
}
}
Multilingual example
Use the permalinks configuration as a component of your localization strategy.
With this content structure:
content/
├── en/
│ ├── books/
│ │ ├── les-miserables.md
│ │ └── the-hunchback-of-notre-dame.md
│ └── _index.md
└── es/
├── books/
│ ├── les-miserables.md
│ └── the-hunchback-of-notre-dame.md
└── _index.mdAnd this site configuration:
defaultContentLanguage: en
defaultContentLanguageInSubdir: true
languages:
en:
contentDir: content/en
languageCode: en-US
languageDirection: ltr
languageName: English
permalinks:
page:
books: /books/:slug/
section:
books: /books/
weight: 1
es:
contentDir: content/es
languageCode: es-ES
languageDirection: ltr
languageName: Español
permalinks:
page:
books: /libros/:slug/
section:
books: /libros/
weight: 2
defaultContentLanguage = 'en'
defaultContentLanguageInSubdir = true
[languages]
[languages.en]
contentDir = 'content/en'
languageCode = 'en-US'
languageDirection = 'ltr'
languageName = 'English'
weight = 1
[languages.en.permalinks]
[languages.en.permalinks.page]
books = '/books/:slug/'
[languages.en.permalinks.section]
books = '/books/'
[languages.es]
contentDir = 'content/es'
languageCode = 'es-ES'
languageDirection = 'ltr'
languageName = 'Español'
weight = 2
[languages.es.permalinks]
[languages.es.permalinks.page]
books = '/libros/:slug/'
[languages.es.permalinks.section]
books = '/libros/'
{
"defaultContentLanguage": "en",
"defaultContentLanguageInSubdir": true,
"languages": {
"en": {
"contentDir": "content/en",
"languageCode": "en-US",
"languageDirection": "ltr",
"languageName": "English",
"permalinks": {
"page": {
"books": "/books/:slug/"
},
"section": {
"books": "/books/"
}
},
"weight": 1
},
"es": {
"contentDir": "content/es",
"languageCode": "es-ES",
"languageDirection": "ltr",
"languageName": "Español",
"permalinks": {
"page": {
"books": "/libros/:slug/"
},
"section": {
"books": "/libros/"
}
},
"weight": 2
}
}
}
The structure of the published site will be:
public/
├── en/
│ ├── books/
│ │ ├── les-miserables/
│ │ │ └── index.html
│ │ ├── the-hunchback-of-notre-dame/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
├── es/
│ ├── libros/
│ │ ├── les-miserables/
│ │ │ └── index.html
│ │ ├── the-hunchback-of-notre-dame/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
└── index.htmlTokens
Use these tokens when defining a URL pattern.
:year- The 4-digit year as defined in the front matter
datefield. :month- The 2-digit month as defined in the front matter
datefield. :monthname- The name of the month as defined in the front matter
datefield. :day- The 2-digit day as defined in the front matter
datefield. :weekday- The 1-digit day of the week as defined in the front matter
datefield (Sunday =0). :weekdayname- The name of the day of the week as defined in the front matter
datefield. :yearday- The 1- to 3-digit day of the year as defined in the front matter
datefield. :section- The content’s section.
:sectionslug- New in v0.149.0
- The content’s section using slugified section name. The slugified section name is the
slugas defined in front matter, else thetitleas defined in front matter, else the automatic title. :sections- The content’s sections hierarchy. You can use a selection of the sections using slice syntax:
:sections[1:]includes all but the first,:sections[:last]includes all but the last,:sections[last]includes only the last,:sections[1:2]includes section 2 and 3. Note that this slice access will not throw any out-of-bounds errors, so you don’t have to be exact. :sectionslugs- New in v0.149.0
- The content’s sections hierarchy using slugified section names. The slugified section name is the
slugas defined in front matter, else thetitleas defined in front matter, else the automatic title. You can use a selection of the sections using slice syntax::sectionslugs[1:]includes all but the first,:sectionslugs[:last]includes all but the last,:sectionslugs[last]includes only the last,:sectionslugs[1:2]includes section 2 and 3. Note that this slice access will not throw any out-of-bounds errors, so you don’t have to be exact. :title- The
titleas defined in front matter, else the automatic title. Hugo generates titles automatically for section, taxonomy, and term pages that are not backed by a file. :slug- The
slugas defined in front matter, else thetitleas defined in front matter, else the automatic title. Hugo generates titles automatically for section, taxonomy, and term pages that are not backed by a file. :filename- The content’s file name without extension, applicable to the
pagepage kind.Deprecated in v0.144.0
The
:filenametoken has been deprecated. Use:contentbasenameinstead. :slugorfilename- The
slugas defined in front matter, else the content’s file name without extension, applicable to thepagepage kind.Deprecated in v0.144.0
The
:slugorfilenametoken has been deprecated. Use:slugorcontentbasenameinstead. :contentbasename- New in v0.144.0
- The content base name.
:slugorcontentbasename- New in v0.144.0
- The
slugas defined in front matter, else the content base name.
For time-related values, you can also use the layout string components defined in Go’s time package. For example:
permalinks:
posts: /:06/:1/:2/:title/
[permalinks]
posts = '/:06/:1/:2/:title/'
{
"permalinks": {
"posts": "/:06/:1/:2/:title/"
}
}
