quarto-dev / quarto-dev/quarto-cli

quarto preview of a document outside website output-dir publishes Browse at .../../file.html and 404s

Open Beginner friendly
#14,762 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug preview
Dominant language
JavaScript
Stars
6k
Forks
458
Avg merge
1d 9h
Merged PRs (30d)
41

Description

I have:
  • searched the issue tracker for similar issues
  • installed the latest version of Quarto CLI
  • formatted my issue following the Bug Reports guide
Bug description
Bug description

In a website project with output-dir, previewing a document that is not written into that output directory still uses the website preview server (rooted at output-dir). The browse URL becomes something like:

Browse at http://localhost:PORT/../_draft.html

The browser/IDE normalizes that to /_draft.html, which is not served from output-dir, so the preview pane gets 404. The HTML file itself is rendered successfully next to the source.

This looks related to the #13804 / #14298 / #14300 preview-path work: #14300 fixed the single-file (isSingleFile) case, but not the case where a real website project renders a file outside projectOutputDir.

Steps to reproduce
Steps to reproduce
mkdir -p repro && cd repro
cat > _quarto.yml <<'EOF'
project:
  type: website
  output-dir: _output
  render:
    - index.qmd
EOF

cat > index.qmd <<'EOF'
---
title: Site
---
Hello site
EOF

cat > _draft.qmd <<'EOF'
---
title: Draft
format: html
---
Hello draft
EOF

# Build the site once so _output/ exists
quarto render

# Preview the draft (not in render list; HTML lands next to source)
quarto preview _draft.qmd --no-browser --no-watch-inputs --port 5678

Observe:

Output created: _draft.html
Browse at http://localhost:5678/../_draft.html

Then:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5678/          # 200 (index)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5678/_draft.html # 404
ls _draft.html _output/_draft.html
# _draft.html exists; _output/_draft.html does not

Same failure happens for a non-underscore file that is also omitted from project.render (so output is still written beside the source, not into _output).

Actual behavior
  • Browse URL includes ../filename.html
  • Preview server is still projectHtmlFileRequestHandler rooted at _output
  • Requested path 404s
  • VS Code / Cursor Quarto preview is unusable for these docs even though render succeeded
Suggested fix direction

In previewInitialPath() / handler selection in src/command/preview/preview.ts, when

relative(projectOutputDir(project), outputFile)

escapes the output dir (starts with ..), treat it like single-file preview (htmlFileRequestHandler + empty initial path) instead of the website handler.

Expected behavior

Preview should serve the rendered document successfully. For outputs outside projectOutputDir, it should fall back to the single-file handler / root URL behavior (as #14300 did for isSingleFile), e.g.:

  • Browse at http://localhost:PORT/
  • GET / → 200 with the draft HTML
Workarounds
  1. quarto render draft.qmd and open the .html directly
  2. Temporarily move/rename _quarto.yml so preview runs in single-file mode
  3. Add the file to the website render: list so output lands under output-dir
Your environment
  • IDE: Cursor / VS Code Quarto preview (quarto preview … --no-browser --no-watch-inputs)
  • OS: macOS (darwin 25)
Quarto check output
Quarto 1.10.18
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.10.0: OK
      Dart Sass version 1.101.0: OK
      Deno version 2.7.14: OK
      Typst version 0.15.1: OK
[✓] Checking Quarto installation......OK
      Version: 1.10.18
      Path: /Applications/quarto/bin

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/command/preview/preview.ts, focusing on previewInitialPath() and the handler-selection logic. Run the supplied website project reproduction with an omitted document, then trace how a path outside projectOutputDir is handled. Done means the draft is served successfully at the root URL instead of producing a ../ URL and a 404.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.