Is there an easy way or option to host multiple rendered html Quarto Books under a single local web server?

I want to keep multiple different project html documents of Quarto Books without re-rendering in future, like:

~/Sites/
 |- project_a / index.html
 |- project_b / index.html

Q1. Is there such an option to achieve this?
I tried site-url: report_book_search_my and site-path: report_book_search_my, but they do not change the root path in index.html.

Q2. If there's no such option, what is a good way to achieve multiple projects hosted under a single web server at local?

In order to keep the rendered html documents of Quarto Book with search functionality available in future without re-rendering, we need a local web server. This is because javascript-depending search functionality does not work if we open local html file on modern browsers as file:// (i.e. just open the index.html on a browser) because of CORS (cross-origin resource sharing)-security issue.

Under a web server, this can be achieved as follows, as far as I only want single project just below the document root.

mkdir ~/Sites
cd ~/Sites
npx serve .
#http://localhost:3000
#click deny to keep it local when macos asks if inbound connection is allowed or not. 
ln -s <my_quarto_dir>/_book ~/Sites/<any_name_i_want>

But it does not work if we want to organize multiple project directories under ~/Sites/ as above. This is because index.html assumes root as / such as these:

<script src="site_libs/quarto-nav/quarto-nav.js"></script>
<script src="site_libs/quarto-nav/headroom.min.js"></script>
...
  <a href="./index.html" class="sidebar-item-text sidebar-link active">
...
  <a href="./intro.html" class="sidebar-item-text sidebar-link">
...

I couldn't find an option to change document root when we render (or publish to any user-defined web server).

My workaround is as follows:

  1. Create scripts/add-base.sh to add <base> tag to change document root.
  • add-base.sh
#!/bin/bash

mv _book/index.html _book/index.orig.html

name=$(basename "$(pwd)")

# path-absolute-URL string like `/foo` with trailing `/`, i.e. `/foo/` works. 
# to add e.g. `<base href="/report_book_search/">`
perl -spe 's!\<head\>\n!\<head\>\n\<base href\="/$name/">\n!;' -- -name=$name _book/index.orig.html > _book/index.html

# scheme-relative-special-URL string works, too. 
# to add e.g. `<base href="http://localhost:3000/report_book_search/">`
#perl -spe 's!\<head\>\n!\<head\>\n\<base href\="http://localhost:3000\/$name/">\n!;' -- -name=$name _book/index.orig.html > _book/index.html

# path-relative URL string like <base href="./report_book_search/"> does not work.  (some links fails with '/' at the end or url such as `http://localhost:3000/report_book_search/`.)

rm ~/Sites/$name
ln -s -f "$(pwd)"/_book ~/Sites/$name
  1. Add 2 lines of post-render: at project: section of yaml as follows.
project:
  type: book
  post-render: 
    - scripts/add-base.sh

These steps enable multiple projects hosted under a single web server. (When to test on RStudio with http://localhost:<portnum>, comment out these two lines).



But I wonder is there easier and better way to achieve this? Thanks.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.

Sorry for the delay on this one.

Could you open an issue or discussion in https://github.com/quarto-dev/quarto-cli repo with a reproducible example (as a github repo for instance)?

This will help us look into this, as with an example we can run it will be easier to understand what you are observing.

Done, I opened this issue there.
c.f. Multiple rendered html Quarto Books cannot be put under a single local web server. · Issue #11115 · quarto-dev/quarto-cli · GitHub

The solution is as below, thanks to the help by mcanouil at github.

  • Change output dir by adding output-dir: at project: in yml such that rendered dir should be output directly under the desired web server document root.

  • _quarto.yml:

project:
  type: book
  output-dir: /Users/<account>/Sites/mybook7

book:
  site-url: mybook7
  title: "mybook7"
  author: "Norah Jones"
  date: "10/19/2024"
  chapters:
    - index.qmd
    - intro.qmd
    - summary.qmd
    - references.qmd

bibliography: references.bib

format:
  html:
    theme: cosmo
  pdf:
    documentclass: scrreprt
  • Both site-url: mybook7 and site-url: http://localhost:3000/mybook7 work.
  • Note that the softlink approach I described before does not work with this yml contrary to the workaround approach of adding <base> tag like <base href="http://localhost:3000/mybook2/">, despite the file contents are the same. That is, output-dir: <document_root>/mybook7 is mandatory. (It might possibly be because of CORS security issue of recent browser/javascript...)