diff --git a/DESCRIPTION b/DESCRIPTION
index 2a19d56fb10d6fcd325a8ab7a1b8a9b0db9b449a..7c6695b5ff5d86a975b680c89ea5ede90349c1d0 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -11,11 +11,13 @@ RoxygenNote: 7.3.1
 Imports:
     bookdown,
     config,
+    devtools,
     dplyr,
     gert,
     httr,
     jsonlite,
     magrittr,
+    pkgdown,
     pkgload,
     rlang,
     urltools,
diff --git a/NAMESPACE b/NAMESPACE
index 063a3caf40d63172e2d9c81d0f26ff58bf90d6e6..abf7834961a33b2b231d82eb73ef47cfab2a1ba5 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -3,6 +3,7 @@
 export("%>%")
 export(add_gitignore)
 export(add_report)
+export(build_site)
 export(cleanDataCache)
 export(create_fairify)
 export(create_reports)
diff --git a/R/build_site.R b/R/build_site.R
new file mode 100644
index 0000000000000000000000000000000000000000..d3192304e7f446671555c3dc052cba180b43a15c
--- /dev/null
+++ b/R/build_site.R
@@ -0,0 +1,46 @@
+#' Build a fairify website
+#'
+#' @details
+#' In order to create a fairiy website containing fairify reports, this function
+#' runs successively:
+#'
+#' - [devtools::build_readme] if a file README.Rmd exists
+#' - [pkgdown::build_site]
+#' - [render_reports]
+#'
+#' @inheritParams pkgdown::build_site
+#' @inheritParams render_reports
+#' @param ... Further parameters to pass to [render_reports]
+#'
+#' @return Used for side effects
+#' @export
+#'
+build_site <- function(pkg = pkgload::pkg_path(),
+                       examples = TRUE,
+                       run_dont_run = FALSE,
+                       seed = 1014,
+                       lazy = FALSE,
+                       override = list(),
+                       preview = NA,
+                       devel = TRUE,
+                       new_process = !devel,
+                       install = !devel,
+                       reports_dir = file.path(pkg, "reports"),
+                       ...) {
+  if (file.exists(file.path(pkg, "README.Rmd"))) {
+    devtools::build_readme(path = pkg)
+  }
+  unlink(file.path(pkg, "public"), recursive = TRUE)
+  pkgdown::build_site(pkg = pkg,
+                      examples  = examples,
+                      run_dont_run  = run_dont_run,
+                      seed  = seed,
+                      lazy  = lazy,
+                      override  = override,
+                      preview  = preview,
+                      devel  = devel,
+                      new_process  = new_process,
+                      install  = install)
+  render_reports(reports_dir = reports_dir, ...)
+  invisible(TRUE)
+}
diff --git a/R/create_fairify.R b/R/create_fairify.R
index 39622189c953093da3dafbf8ab820c43912642e2..e7cdf5de6d71d11b6cf7f7dc2ed0e83f677c5327 100644
--- a/R/create_fairify.R
+++ b/R/create_fairify.R
@@ -6,7 +6,9 @@
 #' @param tidy if `TRUE`, run [usethis::use_testthat()], and [usethis::use_tidy_description()]
 #' @param reports If `TRUE`, run `create_reports`, preparing package structure for report publications
 #' @param cloud If `TRUE`, copy fairify functions for cloud capabilities
-#' @param git if `TRUE`, initialises a Git repository
+#' @param git if `TRUE`, initialise a Git repository
+#' @param pkgdown if `TRUE`, initialise a pkgdown web site (See [usethis::use_pkgdown])
+#' @param destdir Target directory for pkgdown website and reports
 #' @param ... Further parameters passed to [usethis::create_package]
 #'
 #' @return Use for side effect.
@@ -24,26 +26,43 @@ create_fairify <-
            reports = TRUE,
            cloud = TRUE,
            git = TRUE,
+           pkgdown = TRUE,
+           destdir = "public",
            fields = list(Remotes = "git::https://forgemia.inra.fr/umr-g-eau/fairify.git"),
            ...) {
+
     usethis::create_package(path,
                             fields = fields,
                             open = FALSE,
                             check_name = check_name,
                             ...)
     usethis::proj_set(path)
+    usethis::use_package("fairify", "Depends")
+
     if (cloud) update_fairify(path)
+
     if (tidy) {
       usethis::local_project(path)
       usethis::use_tidy_description()
     }
+
     if (git) {
       gert::git_init(path)
       add_gitignore(path)
     }
-    if (reports)
-      create_reports(path = path, git = git)
-    usethis::use_package("fairify", "Depends")
+
+    if (reports) create_reports(path = path, git = git)
+
+    if(pkgdown) {
+      config_file <- "_pkgdown.yml"
+      usethis::use_build_ignore(c(config_file, destdir, "pkgdown"))
+      usethis::use_git_ignore(destdir)
+      config <- list(url = NULL)
+      config$template <- list(bootstrap = 5L)
+      config$destination <- destdir
+      writeLines(yaml::as.yaml(config), file.path(path, config_file))
+    }
+
     message("Fairify project created")
     message("Don't forget to edit the file `inst/config.yml` for configuring the data location for your project")
     if (open) {
diff --git a/man/build_site.Rd b/man/build_site.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..2b678941550e3c00fd889c0c70a3ae99e12fc48a
--- /dev/null
+++ b/man/build_site.Rd
@@ -0,0 +1,80 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/build_site.R
+\name{build_site}
+\alias{build_site}
+\title{Build a fairify website}
+\usage{
+build_site(
+  pkg = pkgload::pkg_path(),
+  examples = TRUE,
+  run_dont_run = FALSE,
+  seed = 1014,
+  lazy = FALSE,
+  override = list(),
+  preview = NA,
+  devel = TRUE,
+  new_process = !devel,
+  install = !devel,
+  reports_dir = file.path(pkg, "reports"),
+  ...
+)
+}
+\arguments{
+\item{pkg}{Path to package.}
+
+\item{examples}{Run examples?}
+
+\item{run_dont_run}{Run examples that are surrounded in \\dontrun?}
+
+\item{seed}{Seed used to initialize so that random examples are
+reproducible.}
+
+\item{lazy}{If \code{TRUE}, will only rebuild articles and reference pages
+if the source is newer than the destination.}
+
+\item{override}{An optional named list used to temporarily override
+values in \verb{_pkgdown.yml}}
+
+\item{preview}{If \code{TRUE}, or \code{is.na(preview) && interactive()}, will preview
+freshly generated section in browser.}
+
+\item{devel}{Use development or deployment process?
+
+If \code{TRUE}, uses lighter-weight process suitable for rapid
+iteration; it will run examples and vignettes in the current process,
+and will load code with \code{pkgload::load_all()}.
+
+If \code{FALSE}, will first install the package to a temporary library,
+and will run all examples and vignettes in a new process.
+
+\code{build_site()} defaults to \code{devel = FALSE} so that you get high fidelity
+outputs when you building the complete site; \code{build_reference()},
+\code{build_home()} and friends default to \code{devel = TRUE} so that you can
+rapidly iterate during development.}
+
+\item{new_process}{If \code{TRUE}, will run \code{build_site()} in a separate process.
+This enhances reproducibility by ensuring nothing that you have loaded
+in the current process affects the build process.}
+
+\item{install}{If \code{TRUE}, will install the package in a temporary library
+so it is available for vignettes.}
+
+\item{reports_dir}{\link{character} path for the reports}
+
+\item{...}{Further parameters to pass to \link{render_reports}}
+}
+\value{
+Used for side effects
+}
+\description{
+Build a fairify website
+}
+\details{
+In order to create a fairiy website containing fairify reports, this function
+runs successively:
+\itemize{
+\item \link[devtools:build_rmd]{devtools::build_readme} if a file README.Rmd exists
+\item \link[pkgdown:build_site]{pkgdown::build_site}
+\item \link{render_reports}
+}
+}
diff --git a/man/create_fairify.Rd b/man/create_fairify.Rd
index 2d721c916ee4f77f551ce612c928e1cec780826d..2b7c88c22500bbd7becdaded729f57f7bfaecf04 100644
--- a/man/create_fairify.Rd
+++ b/man/create_fairify.Rd
@@ -12,6 +12,8 @@ create_fairify(
   reports = TRUE,
   cloud = TRUE,
   git = TRUE,
+  pkgdown = TRUE,
+  destdir = "public",
   fields = list(Remotes = "git::https://forgemia.inra.fr/umr-g-eau/fairify.git"),
   ...
 )
@@ -36,7 +38,11 @@ error if not.}
 
 \item{cloud}{If \code{TRUE}, copy fairify functions for cloud capabilities}
 
-\item{git}{if \code{TRUE}, initialises a Git repository}
+\item{git}{if \code{TRUE}, initialise a Git repository}
+
+\item{pkgdown}{if \code{TRUE}, initialise a pkgdown web site (See \link[usethis:use_pkgdown]{usethis::use_pkgdown})}
+
+\item{destdir}{Target directory for pkgdown website and reports}
 
 \item{fields}{A named list of fields to add to \code{DESCRIPTION}, potentially
 overriding default values. See \code{\link[usethis:use_description]{use_description()}} for how you can set
diff --git a/tests/testthat/test-build_site.R b/tests/testthat/test-build_site.R
new file mode 100644
index 0000000000000000000000000000000000000000..f4b373be090697234153df39e930620935b25c91
--- /dev/null
+++ b/tests/testthat/test-build_site.R
@@ -0,0 +1,14 @@
+skip_on_ci()
+
+test_that("build_site works", {
+  path <- helper_create_fairify()
+  add_report("my_report", path)
+  build_site(path)
+  site_path <- file.path(path, "public")
+  expect_true(dir.exists(site_path))
+  expect_true(file.exists(file.path(site_path, "index.html")))
+  report_path <- file.path(path, "public/reports/my_report")
+  expect_true(dir.exists(report_path))
+  expect_true(file.exists(file.path(report_path, "index.html")))
+  unlink(path, recursive = TRUE)
+})