Skip to content

fe-web: improve interfaces for website embedding #1375

@micahscopes

Description

@micahscopes

Context

While integrating the fe doc viewer and <fe-code-block> into the Astro/Starlight website (www PR #8), we hit several interface gaps that required workarounds. This issue tracks the changes needed to make embedding clean.

Current Pain Points

1. Shadow DOM stylesheet resolution

_getCodeBlockSheet() in fe-code-block.js only scans <style> tags for highlight CSS. A <link rel="stylesheet"> (the standard web approach) doesn't work. Host sites have to inline the CSS via raw imports.

2. Click navigation hardcodes location.hash

fe-code-block.js line 426 does location.hash = "#" + docPath. Doesn't check FE_DOCS_BASE. Breaks when embedded on a page that isn't the SPA viewer (pollutes URL, breaks back button). Required a hashchange listener with replaceState workaround.

3. Global namespace pollution

window.FE_SCIP, window.FE_DOCS_BASE, window.FE_DOC_INDEX, window.feHighlight, window.feUnhighlight, window.FeHighlighter, etc. The bundle can't be loaded as type="module" because these functions need to be global for the custom elements to find them.

4. Monolithic static output

fe doc static produces a single 5.7MB HTML file with everything inlined (styles, SCIP data, doc data, JS). Can't override theme via CSS cascade. Can't add custom head elements. Can't serve individual assets from CDN.

5. No navigation control for embedded code blocks

When <fe-code-block> is on a page outside the doc viewer, all symbol clicks navigate unconditionally. No way to filter (e.g., "only link stdlib types, not local definitions") or intercept (e.g., "open in new tab" or "show popover").

6. Empty SCIP file key

fe doc json on a single file produces "" as the file path key in scip.files.

Proposed Changes (prioritized)

P0: Fix shadow DOM stylesheet resolution

Support <link> stylesheets in _getCodeBlockSheet(), not just inline <style> tags. Check document.styleSheets for linked stylesheets containing the highlight rules.

P0: Navigation via CustomEvent

Before mutating location, dispatch a cancellable CustomEvent("fe-navigate", { detail: { symbol, docPath } }). Host pages can preventDefault() to handle navigation themselves. Fall back to current behavior if not cancelled. This replaces both the FE_DOCS_BASE check AND the link filtering need.

P1: Proper module exports

Assign globals explicitly (window.feHighlight = feHighlight) in the bundle so type="module" works. Long-term, move toward attribute/property-based configuration on the custom elements rather than globals.

P1: Split static output

fe doc static should output separate files (index.html shell, fe-web.js, fe-highlight.css, docs.json) that can be composed with normal web tooling. The monolithic mode could remain as a --self-contained flag.

P2: Fix empty SCIP file key

Use the filename when the relative path would be empty.

P2: Configuration via element attributes

Move toward <fe-code-block src="..." base="..."> instead of global window.FE_DOCS_BASE. The custom element discovers its own configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions