This vignette teaches you how to customise the style/design of your
pkgdown site. We’ll start by discussing two techniques that only require
tweaks to your _pkgdown.yml
: theming (colours and fonts)
and layout (content of the navbar, sidebar, footer, …). We’ll then
discuss how to add additional HTML and other files. Next, we’ll discuss
how to give multiple sites the same style using a package, then finish
up with some workflow advice.
Getting started
Most theming features work only with Bootstrap 5, so first update
your site by adding the following lines to your
_pkgdown.yml
:
template:
bootstrap: 5
Overall, the site should look pretty similar, but you will notice a number of small improvements. Most importantly, the default font is much bigger, making it considerably easier to read. Upgrading to Bootstrap 5 has a low chance of breaking your site unless you were using your own pkgdown templates or custom CSS.
Theming
There are two ways to change the visual style of your site from
_pkgdown.yml
: using a pre-packaged bootswatch theme or
customising theme variables with bslib. The following sections show you
how.
Bootswatch themes
The easiest way to change the entire appearance of your website is to use a Bootswatch theme:
template:
bootstrap: 5
bootswatch: materia
Changing the bootswatch theme affects both the HTML (via the navbar,
more on that below) and the CSS, so you’ll need to re-build your
complete site with build_site()
to fully appreciate the
changes. While you’re experimenting, you can speed things up by just
rebuilding the home page and the CSS by running
build_home_index(); init_site()
(and then refreshing the
browser).
Bootswatch templates with tall navbars (e.g. lux, pulse) also require
that you set the pkgdown-nav-height
bslib variable:
template:
bootstrap: 5
bootswatch: lux
bslib:
pkgdown-nav-height: 100px
You can find the correct height by running
$(".navbar").outerHeight()
in the javascript
console.
bslib variables
Instead of picking a complete theme, you can tweak fonts and colours individually using bslib variables. bslib is an R package that wraps sass, the tool that Boostrap uses to produce CSS from a special language called scss. The primary advantage of scss over CSS is that it’s more programmable, so you can have a few key bslib variables that affect appearance of many HTML elements.
There are three key variables that affect the colour:
-
bg
(background) determines the page background. -
fg
(foreground) determines the text colour.bg
andfg
are mixed to yieldgray-100
,gray-200
, …,grey-900
, which are used to style other elements to match the overall colour scheme. -
primary
sets the link colour and the (translucent) hover colour in the navbar and sidebar.
template:
bootstrap: 5
bslib:
bg: "#202123"
fg: "#B8BCC2"
primary: "#306cc9"
You can customise other components by setting more specific bslib
variables, taking advantage of inheritance where possible. For example,
table-border-color
defaults to border-color
which defaults to gray-300
. If you want to change the
colour of all borders, you can set border-color
; if you
just want to change the colour of table borders, you can set
table-border-color
. You can find a full list of variables
in vignette("bs5-variables", package = "bslib")
.
You can also override the default fonts used for the majority of the
text (base_font
), for headings (heading_font
)
and for code (code_font
). The easiest way is to supply the
name of a Google font:
template:
bootstrap: 5
bslib:
base_font: {google: "Roboto"}
heading_font: {google: "Roboto Slab"}
code_font: {google: "JetBrains Mono"}
While iterating on colours and other variables you only need to rerun
init_site()
and refresh your browser; when iterating on
fonts, you’ll need to run
build_home_index(); init_site()
.
Syntax highlighting
The colours used for syntax highlighting in code blocks are
controlled by the theme
setting:
template:
bootstrap: 5
theme: breeze-light
You can choose from any of the following options: a11y-dark, a11y-light, arrow-dark, arrow-light, atom-one-dark, atom-one-light, ayu-dark, ayu-light, ayu-mirage, breeze-dark, breeze-light, breezedark, dracula, espresso, github-dark, github-light, gruvbox-dark, gruvbox-light, haddock, kate, monochrome-dark, monochrome-light, monochrome, monokai, nord, oblivion, printing, pygments, radical, solarized-dark, solarized-light, solarized, tango, vim-dark, zenburn.
Bootswatch themes with a dark background (e.g. cyborg, darkly, solar)
will need a dark syntax highlighting theme
,
e.g. arrow-dark
:
template:
bootstrap: 5
bootswatch: cyborg
theme: arrow-dark
The foreground and background colours used for inline code are
controlled by code-color
and code-bg
bslib
variables. If you want inline code to match code blocks, you’ll need to
override the variables yourself, e.g.:
template:
bootstrap: 5
theme: arrow-dark
bslib:
code-bg: "#2b2b2b"
Navbar style
The primary navbar colours are determined by HTML classes, not CSS,
and can be customized using the navbar
fields
bg
and type
which control the background and
foreground colours respectively. Typically bg
will be one
of light
, dark
, or primary
:
navbar:
bg: primary
You generally don’t need to set bg
if you use a
bootswatch theme, as pkgdown will pick the bg
used on the
Bootstwatch preview. Similarly,
you don’t usually need to set type
because bootstrap will
guess it for you. If it guesses wrong, override with
type: light
or type: dark
depending on whether
the background colour is light (so you need dark text) or
type: dark
if the background is dark (so you need light
text). Unfortunately, these are defined relative to the page background,
so if you have a dark site you’ll need to flip light
and
dark
(a little experimentation should quickly determine
what looks best).
Because the navbar is styled with HTML, you’ll need to
build_home_index(); init_site()
to see the effect of
changing this parameter.
Layout
You can customise the contents of the navbar, footer, and home page
sidebar using the navbar
, footer
, and
sidebar
fields. They all use a similar structure that
separately defines the overall structure
and the individual
components
.
Navbar
You can customise the navigation bar that appears at the top of the
page with the navbar
field. It’s made up of two pieces:
structure
, which defines the overall layout, and
components
, which defines what each piece looks like. This
organisation makes it easy to mix and match pkgdown defaults with your
own customisations.
This is the default structure:
navbar:
structure:
left: [intro, reference, articles, tutorials, news]
right: [search, github]
It makes use of the the six built-in components:
-
intro
: “Get Started”, which links to a vignette with the same name as the package. -
reference
, if there are any.Rd
files. -
articles
, if there are any vignettes or articles. -
tutorials
, if there any tutorials. -
news
, ifNEWS.md
exists. -
search
, the search box (seevignette("search")
for more details). -
github
, a link to the source repository (with an icon), if it can be automatically determined from theDESCRIPTION
.
You can use the structure
field to reorganise the navbar
without changing the default contents:
navbar:
structure:
left: [search]
right: [reference, articles]
You can use components
to override the default content.
For example, this yaml provides a custom articles menu:
navbar:
components:
articles:
text: Articles
menu:
- text: Category A
- text: Title A1
href: articles/a1.html
- text: Title A2
href: articles/a2.html
- text: -------
- text: "Category B"
- text: Article B1
href: articles/b1.html
Components uses the same syntax as RMarkdown
menus. The elements of menu
can be:
A link (
text
+href
)A heading (just
text
)A separator (
text: ——–
)
Instead of text, you can also use the name of an icon
s
from fontawesome.
You should also provide a textual description in the
aria-label
field for screenreader users.
To add a new component to the navbar, you need to modify both
structure
and components
. For example, the
following yaml adds a new “twitter” component that appears to the left
of the github icon.
navbar:
structure:
right: [twitter, github]
components:
twitter:
icon: fa-twitter
href: http://twitter.com/hadleywickham
aria-label: Twitter
Finally, you can add arbitrary HTML to three locations in the navbar:
template:
includes:
before_title: <!-- inserted before the package title in the header ->
before_navbar: <!-- inserted before the navbar links -->
after_navbar: <!-- inserted after the navbar links -->
These includes will appear on all screen sizes, and will not be collapsed into the the navbar drop down.
Footer
You can customise the footer with the footer
field. It’s
made up of two pieces: structure
, which defines the overall
layout, and components
, which defines what each piece looks
like. This organisation makes it easy to mix and match the pkgdown
defaults with your own customisations.
This is the default structure:
footer:
structure:
left: developed_by
right: built_with
Which uses two of the three built-in components:
-
developed_by
, a sentence describing the main authors of the package. (See?build_home
if you want to tweak which authors appear in the footer.) -
built_with
, a sentence advertising pkgdown. -
package
, the name of the package.
You can override these defaults with the footer
field.
The example below puts the authors’ information on the right along with
a legal disclaimer, and puts the pkgdown link on the left.
footer:
structure:
left: pkgdown
right: [authors, legal]
components:
legal: Provided without **any warranty**.
Each side is pasted into a single string (separated by
" "
) and then converted from markdown to HTML.
Sidebar
You can customise the homepage sidebar with the
home.sidebar
field. It’s made up of two pieces:
structure
, which defines the overall layout, and
components
, which defines what each piece looks like. This
organisation makes it easy to mix and match the pkgdown defaults with
your own customisations.
This is the default structure:
home:
sidebar:
structure: [links, license, community, citation, authors, dev]
These are drawn from seven built-in components:
-
links
: automated links generated fromURL
andBugReports
fields fromDESCRIPTION
plus manual links from thehome.links
field:home: links: - text: Link text href: https://website.com - text: Roadmap href: /roadmap.html
license
: Licensing information ifLICENSE
/LICENCE
orLICENSE.md
/LICENCE.md
files are present.community
: links to to.github/CONTRIBUTING.md
,.github/CODE_OF_CONDUCT.md
, etc.citation
: link to package citation information. Uses eitherinst/CITATION
or, if absent, information from theDESCRIPTION
.authors
: selected authors from theDESCRIPTION
.dev
: development status badges extracted fromREADME.md
/index.md
. This is only shown for “development” versions of websites; see “Development mode” in?build_site
for details.toc
: a table of contents for the README (not shown by default).
You can also add your own components, where text
is
markdown text:
home:
sidebar:
structure: [authors, custom, toc, dev]
components:
custom:
title: Funding
text: We are *grateful* for funding!
Alternatively, you can provide a ready-made sidebar HTML:
home:
sidebar:
html: path-to-sidebar.html
Or completely remove it:
home:
sidebar: FALSE
Additional HTML and files
If you need to include additional HTML, you can add it in the following locations:
template:
includes:
in_header: <!-- inserted at the end of the head -->
before_body: <!-- inserted at the beginging of the body -->
after_body: <!-- inserted at the end of the body -->
before_title: <!-- inserted before the package title in the header ->
before_navbar: <!-- inserted before the navbar links -->
after_navbar: <!-- inserted after the navbar links -->
You can include additional files by putting them in the right place:
pkgdown/extra.css
andpkgdown/extra.js
will be copied in to rendered site and linked from<head>
(after the pkgdown defaults).pkgdown/extra.scss
will be added to the scss ruleset used to generate the site CSS.Any files in
pkgdown/assets
will be copied to the website root directory.For expert users: template files in
pkgdown/templates
will override layout templates provided by pkgdown or template packages.
Use init_site()
to update your rendered website after
making changes to these files.
Template packages
To share a pkgdown style across several packages, the best workflow is to create… a package! It can contain any of the following:
- A configuration file in
inst/pkgdown/_pkgdown.yml
. This can be used to set (e.g.) author definitions, Bootstrap version and variables, the sidebar, footer, navbar, etc. - Templates in
inst/pkgdown/templates/
will override the default templates. - Assets in
inst/pkgdown/assets/
will be copied in to the destination directory. -
inst/pkgdown/extra.scss
will be added to the bslib ruleset.
Any configuration/files supplied will override the pkgdown defaults, but will be overridden by site specific settings.
Once you have created your template package theverybest
,
you can use it by:
-
Setting it as your sites theme:
template: package: theverybest
-
If you’re building your site using GitHub actions or other similar tool, you’ll also need to installed
theverybest
. If you’re using the r-lib pkgdown workflow, you can add the following line to yourDESCRIPTION
:Config/Needs/website: theverybest
To get some sense of how a theming package works, you can look at:
- tidytemplate used for tidyverse and tidymodels packages;
- quillt used for R Markdown packages;
- rotemplate used for rOpenSci packages.
But please note that these templates aren’t suitable for use with your own package as they’re all designed to give a common visual identity to a specific family of packages.
Porting a template package
If you are updating a template package that works with pkgdown 1.0.0,
create directories inst/pkgdown/BS5/templates
and
inst/pkgdown/BS5/assets
(if you don’t have any
templates/assets make sure to a add dummy file to ensure that git tracks
them). The templates
and assets
directories
directly under inst/pkgdown
will be used by pkgdown 1.0.0
and by pkgdown 2.0.0 if boostrap: 3
. The directories under
inst/pkgdown/BS5/
will be used for pkgdown 2.0.0 with
boostrap: 5
. This lets your package support both versions
of bootstrap and pkgdown.
PR previews
Lastly, it might be useful for you to get a preview of the website in internal pull requests. For that, you could use Netlify and GitHub Actions (or apply a similar logic to your toolset):
- Create a new Netlify website (either from scratch by dragging and
dropping a simple index.html, or by creating a site from a GitHub
repository and then unlinking that repository); from the site settings
get its ID to be saved as
NETLIFY_SITE_ID
in your repo secrets; from your account developer settings get a token to be saved asNETLIFY_AUTH_TOKEN
in your repo secrets. - Starting from the standard pkgdown workflow
usethis::use_github_action("pkgdown")
, add some logic to build the site and deploy it to Netlify for pull requests from inside the repository, not pull requests from forks. Example workflow.
Conclusion
In this vignette we explained how to change the theming and layout of pkgdown websites. Further work to improve user experience will involve:
- Working on the article (
?build_articles
) and reference indexes (?build_reference
). - Writing a compelling README that explains why your package is so cool/useful/fun.
- Improving the contents of the individual articles and reference topics 😉.