Writing JavaScript as an inline string in R is always going to be icky, but I think it makes sense when you have a short, one-off function that's only used for your table. Colocating logic can also help with readability, since you don't have to jump around to different files. And the code is completely self-contained so you can change it or move it around easily.
With that said, I do prefer to move JavaScript to an external .js
file when it gets larger and more complicated, and/or when it has to be reused in multiple places. With an external file, you get proper syntax checking and highlighting, linting, auto-formatting, an opportunity to write tests, and freedom from horrible string escaping headaches.
R Markdown
With R Markdown documents, you can use a js
language chunk to include an external script (useful for optionally showing the actual JS code with echo=TRUE
):
```{js, file='script.js', echo=FALSE}
```
Note: this example assumes script.js
is in the same directory as the R Markdown document, so change this to path/to/somewhere-else/script.js
for a different location.
You can also include the script in the document using a <script>
HTML tag:
<script src="script.js"></script>
This HTML goes directly in the document, outside of any code chunk. R Markdown understands <script>
tags and will embed the contents of your script within the rendered HTML document.
Shiny
For Shiny apps, you have more options, and I'll refer to the article on Packaging JavaScript code for Shiny for a detailed summary of each option.
R scripts
R scripts are more tricky, and it depends where you're running the code from - is it from the RStudio IDE, or R from the command line, or RGui?
The RStudio IDE Viewer serves rendered HTML from a local web server, which means browser security features will probably prevent you from directly including a <script>
file from the local filesystem.
Instead, a more robust way to include external scripts is to use htmltools::htmlDependency()
, so the external script works in both the RStudio IDE and everywhere else:
library(reactable)
library(htmltools)
html <- browsable(tagList(
htmlDependency(
# name and version: doesn't really matter, can be anything
"my-script", "0.1.0",
# src: path to directory containing the script (e.g., the current directory '.')
src = normalizePath("."),
# script: filename of script to include
script = "script.js",
# Exclude all other files in src directory
all_files = FALSE
),
reactable(...)
))
# View it directly from an R console
html
# Or save it to an HTML file
save_html(html, "table.html")
This also assumes script.js
is in the current running directory, so change src
to the location of wherever your script is if needed.
And, I also like Matt's answer of reading the external script into R. It's simple and probably works well in most cases.
If you go with the htmlDependency()
approach, you may get additional benefits like automatic deduplication of the script if it's included multiple times in the document. It'll work better if you're reusing the script in multiple tables or writing a package that produces tables with JavaScript dependencies.