Make an art gallery with {bs4cards}

A screenshot of the webpage faxcrayon dot art that has the site title at the top with emojis of a fax machine and a crayon. Below are links to the source and other materials. Below that are some rectangular cards that show some art with the date, title and type of art, like whether its original or a recreation.

Design is, like, a process, so the page may change, y’know?


I used the {bs4cards} package by Danielle Navarro to create an effortless online ‘gallery’ of ‘art’ on a single R Markdown page:

Art is a lie

Turns out you can just put up some pictures on the internet and call it a gallery. No one is stopping you.

Here is a foolproof approach: R Markdown with {bs4cards} to write the content, GitHub Pages to serve it, and a totally rad URL to convince people you’re legit.


The {bs4cards} package (available on CRAN) is great because it lets you create customisable ‘cards’ that you can tile on an R Markdown page.

To create a card, you use the card() function with arguments for title, image,1 text, link, etc. You can put these in a list and pass that to card_grid() to make a grid. Of cards. A card grid.

So, this format could work well to bring disparate information together in one central location, like a blog’s landing page, where a card’s content gives you a preview of post that you can click to visit it.

So I did just that: I made a single page2 where each card displays an art piece I created with R code for #RecreationThursday, or whatever.

The cards contain the creation date in the header; the ‘name’ of the piece as the card title, which links out to where the code is hosted for recreating it; and in the card body it states whether the image is a recreation, a remix or something original.

Example of three cards made use the bs4cards package. Each one has a header with the date in, a square image in the middle, the name of the piece which is a link, and some body text that explains whether the piece is original, a remix or a recreation.

You can find the source on GitHub.

GitHub Pages

One of the easiest ways to serve an R Markdown file on the internet is to store it in a GitHub repository, knit it to HTML and then enable GitHub Pages.

You go to the ‘Pages’ in your repository’s settings to enable it and then your HTML is served so that it’s available to anyone on the internet in the form <>.3


But that doesn’t make for a terribly exciting URL. Since I’m going to be an internationally-famous and extremely financially-successful artist, it makes sense to improve my online brand with a rad URL.

Where to get inspiration? I’ve tweeted images for #RecreationThursday using the fax4 📠 and crayon 🖍 emojis because I was using my rudimentary skills to create facsimile copies of original artworks. So… fax crayon? Like a wax crayon, but, like, fax?

And the <> URL only cost two dollars to buy, so.

There’s a small dance you have to do to make GitHub Pages link to your domain, while your domain provider may themselves require a particular set of settings.

It took half an hour or so for the domain dance to complete, but now the site is available at

Nothing is real

So: {bs4cards}, GitHub Pages and a totally hip URL.

Now I just need to work out how to integrate NFT5 functionality to the site and quit my day job.

Session info
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.1.0 (2021-05-18)
##  os       macOS Big Sur 10.16         
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_GB.UTF-8                 
##  ctype    en_GB.UTF-8                 
##  tz       Europe/London               
##  date     2021-08-01                  
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version    date       lib source                     
##  assertthat    0.2.1      2019-03-21 [1] CRAN (R 4.1.0)             
##  blogdown      1.3        2021-04-14 [1] CRAN (R 4.1.0)             
##  bookdown      0.22       2021-04-22 [1] CRAN (R 4.1.0)             
##  bslib    2021-05-18 [1] CRAN (R 4.1.0)             
##  cli           2.5.0      2021-04-26 [1] CRAN (R 4.1.0)             
##  crayon        1.4.1      2021-02-08 [1] CRAN (R 4.1.0)             
##  digest        0.6.27     2020-10-24 [1] CRAN (R 4.1.0)             
##  emo  2021-06-23 [1] Github (hadley/emo@3f03b11)
##  evaluate      0.14       2019-05-28 [1] CRAN (R 4.1.0)             
##  generics      0.1.0      2020-10-31 [1] CRAN (R 4.1.0)             
##  glue          1.4.2      2020-08-27 [1] CRAN (R 4.1.0)             
##  htmltools    2021-01-22 [1] CRAN (R 4.1.0)             
##  jquerylib     0.1.4      2021-04-26 [1] CRAN (R 4.1.0)             
##  jsonlite      1.7.2      2020-12-09 [1] CRAN (R 4.1.0)             
##  knitr         1.33       2021-04-24 [1] CRAN (R 4.1.0)             
##  lubridate     1.7.10     2021-02-26 [1] CRAN (R 4.1.0)             
##  magrittr      2.0.1      2020-11-17 [1] CRAN (R 4.1.0)             
##  purrr         0.3.4      2020-04-17 [1] CRAN (R 4.1.0)             
##  R6            2.5.0      2020-10-28 [1] CRAN (R 4.1.0)             
##  Rcpp          1.0.6      2021-01-15 [1] CRAN (R 4.1.0)             
##  rlang         0.4.11     2021-04-30 [1] CRAN (R 4.1.0)             
##  rmarkdown     2.9        2021-06-15 [1] CRAN (R 4.1.0)             
##  sass          0.4.0      2021-05-12 [1] CRAN (R 4.1.0)             
##  sessioninfo   1.1.1      2018-11-05 [1] CRAN (R 4.1.0)             
##  stringi       1.6.2      2021-05-17 [1] CRAN (R 4.1.0)             
##  stringr       1.4.0      2019-02-10 [1] CRAN (R 4.1.0)             
##  withr         2.4.2      2021-04-18 [1] CRAN (R 4.1.0)             
##  xfun          0.24       2021-06-15 [1] CRAN (R 4.1.0)             
##  yaml          2.2.1      2020-02-01 [1] CRAN (R 4.1.0)             
## [1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library

  1. You can pass card_image("<path to image>", alt = "Descriptive alt text.") to the image argument of card() to help improve accessibility.↩︎

  2. If you were less lazy than me you could turn this into a fully-blown R Markdown website, so that a card click takes you to a separate page for that piece.↩︎

  3. If you’re feeling fancy, you can call your file ‘index.Rmd’, which knits to ‘index.html’, which GitHub Pages serves with the slightly more succinct URL <>.↩︎

  4. Younglings, the fax machine is an ancient and possibly imaginary piece of technology that’s a mash-up of a telephone, photocopier and printer. All in one!↩︎

  5. Non-Fungible Tokens are Not For ’Thew.↩︎