Skip to content

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

Description

@mrazomej

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpreviewissues related to the `preview` command

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions