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.
In terms of your _pkgdown.yml
, this vignette focusses on
the most important fields nested under template
and
navbar
. To learn more about customising other aspects of
the site, see the documentation for the indiviudal functions like
build_reference()
, build_articles()
,
build_home()
, build_redirects()
, and
init_site()
. To learn about less important fields nested
under template
, see build_site()
.
Most theming features work only with Bootstrap 5, so first update
your site by adding the following lines to your
_pkgdown.yml
:
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.
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.
Please note that pkgdown’s default theme has been carefully optimised
to be accessible, so if you make changes, make sure to also read
vignette("accessibility")
to learn about potential
accessibility pitfalls.
You can provide a “light switch” to allow your users to switch
between dark and light themes by setting the light-switch
template option to true:
This will add a lightswitch
component to the navbar,
which by default appears at the far right. This allows the user to
select light mode, dark mode, or auto mode (which follows the system
setting). The modes are applied using Bootstrap 5.3’s colours
modes so are not separate themes, but a thin layer of colour
customisation applied via CSS.
The easiest way to change the entire appearance of your website is to use a Bootswatch theme:
(Themes are unlikely to work with the light switch, but you can try it and see.)
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. Because
Bootswatch themes are provided by the bslib R package, you can
also nest the bootswatch
field under the bslib
field.
You can find the correct height by running
$(".navbar").outerHeight()
in the javascript
console.
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
and fg
are mixed to yield
gray-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.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
and 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 the bslib
docs.
If you’re using the light switch, many colours are available for customisation specifically for the dark theme.
Theming with bslib is powered by bslib::bs_theme()
and
the bslib
field is a direct translation of the arguments to
that function. As a result, you can fully specify a bslib theme using
the template.bslib
field, making it easy to share YAML with
the output.html_document.theme
field of an
R Markdown document.
While iterating on colours and other variables you only need to rerun
init_site()
and refresh your browser to see the
changes.
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 with the
following syntax:
template:
bootstrap: 5
bslib:
base_font: {google: "Roboto"}
heading_font: {google: "Roboto Slab"}
code_font: {google: "JetBrains Mono"}
If you want to use a non-Google font, you’ll need to do a bit more
work. There are two steps: you need to first configure the font with CSS
and then use it in your _pkgdown.yml
. There are two ways
you might get the CSS:
As a block of CSS which you should put in
pkgdown/extra.scss
or pkgdown/extra.css
. The
CSS will look something like this:
@font-face {
font-family: "proxima-nova";
src:
local("Proxima Nova Regular"),
local("ProximaNova-Regular"),
url("https://example.com/ProximaNova-Regular.eot?#iefix") format("embedded-opentype"),
url("https://example.com/fonts/proxima/ProximaNova-Regular.woff2") format("woff2"),
url("https://example.com/fonts/proxima/ProximaNova-Regular.woff") format("woff"),
url("https://example.com/fonts/proxima/ProximaNova-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: fallback;
}
As a link to a style file, which you’ll need to add to the
<head>
using this syntax:
Then in _pkgdown.yml
you can use the name of the font
you just specified:
Depending on where the font is from (and if you purchased it), you may need to take additional steps to ensure that it can only be used from your site, and/or make sure that it can still be used when you’re previewing locally. If you’re having problems getting a custom font to work, looking for errors in the browser developer console is a good place to start.
When iterating on fonts, you’ll need to run
build_home_index(); init_site()
then refresh your browser
to see the update.
The colours used for syntax highlighting in code blocks are
controlled by the theme
setting:
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
:
If you’re using the light switch, you will want to provide a
theme
and a theme-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.:
By default, pkgdown will render math using mathml. mathml is the
official standard for rendering math on the web, and requires no
additional javascript or css dependencies. However, browser support for
complex math is not always that good, so if you are including complex
equations in your documentation, you may want to switch to either katex
or mathjax
by using the
template.math-rendering
field:
You can customise the contents of the navbar, footer, using the
navbar
and footer
fields. See
?build_home
for how to customise the sidebar on the
homepage. They all use a similar structure that separately defines the
overall structure
and the individual
components
.
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 beginning 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
and pkgdown/extra.js
will be copied to the 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.
To share a pkgdown style across several packages, the best workflow is to create… a package! It can contain any of the following:
inst/pkgdown/_pkgdown.yml
. This
can be used to set (e.g.) author definitions, Bootstrap version and
variables, the sidebar, footer, navbar, etc.inst/pkgdown/templates/
will override the
default templates.inst/pkgdown/assets/
will be copied in to the
destination directory. (Note these files are only copied; you’ll need to
reference them in your stylesheet or elsewhere in order for them to be
actually used.)inst/pkgdown/extra.scss
will be added to the bslib
ruleset. (Note that extra.css
is not supported in
templates.)The pkgdown defaults will be overriden by these template files, which are in turn overridden by package specific settings.
Once you have created your template package theverybest
,
you need to set it as your site’s theme:
You then also need to make sure it’s available when your site is
built. Typically, you won’t want to publish this package to CRAN, but
you will want to publish to GitHub. Once you’ve done that, and assuming
you’re using the usethis
workflow, add the following line to your
DESCRIPTION
:
This will ensure that the GitHub action will automatically install it from GitHub when building your pkgdown site.
To get some sense of how a theming package works, you can look at:
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.
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.
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):
NETLIFY_SITE_ID
in your repo
secrets; from your account developer settings get a token to be saved as
NETLIFY_AUTH_TOKEN
in your repo secrets.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.In this vignette we explained how to change the theming and layout of pkgdown websites. Further work to improve user experience will involve:
?build_articles
) and reference
indexes (?build_reference
).Note that dots (.
) in the package name need
to be replaced by hyphens (-
) in the vignette filename to
be recognized as the intro. That means for a package
foo.bar
the intro needs to be named
foo-bar.Rmd
.↩︎