Skip to content

Goshtoso App Shells

Component Docs Shell

A documentation layout with sidebar search, section navigation, and a table of contents.

componentdocshell Open API documentation

Try it live

A working example with its own navigation, theme controls, and viewport.

Open full example ↗

Navigate between Overview and Activity, search the sidebar, and try the mobile drawer.

Setup and integration

Install and use

Install
go get github.com/araihu/goshtoso-app-shells/[email protected]
Asset handlers and layout
import (
    "net/http"

    "github.com/araihu/goshtoso/assets"
    "github.com/araihu/goshtoso/components/sidebar"
    "github.com/araihu/goshtoso-app-shells/componentdocshell"
    shellassets "github.com/araihu/goshtoso-app-shells/componentdocshell/assets"
)

func registerAssets(mux *http.ServeMux) {
    mux.Handle("GET /assets/", assets.Handler())
    mux.Handle("GET /componentdocshell/assets/", shellassets.Handler())
}

cfg := componentdocshell.Config{
    Brand: componentdocshell.Brand{
        Name: "Product docs",
        HomeURL: "/",
    },
    Navigation: componentdocshell.Navigation{
        Items: []sidebar.Item{{
            ID: "overview", Label: "Overview", Href: "/",
        }},
    },
    Interactions: componentdocshell.InteractionConfig{
        EnableHTMX: true,
        LocalRuntime: true,
    },
}
page := componentdocshell.Page{
    Title: "Overview",
    Active: "overview",
    Content: overviewContent(),
}
view := componentdocshell.Layout(cfg, page)

Add your application’s global search to HeaderActions. The shell’s sidebar search filters local navigation.

Full documents and HTMX fragments

Return Layout for ordinary browser requests. With EnableHTMX enabled, return Fragment when HX-Request-Type is partial. This updates the current page without inserting a second HTML document.

Component Docs Shell Fragment updates the document title and replaces the main content, scoped sidebar, and family navigation out of band, including their active links.

HTTP response selection
func renderDocs(
    writer http.ResponseWriter,
    request *http.Request,
    cfg componentdocshell.Config,
    page componentdocshell.Page,
) {
    view := componentdocshell.Layout(cfg, page)
    if request.Header.Get("HX-Request-Type") == "partial" {
        view = componentdocshell.Fragment(cfg, page)
    }
    if err := view.Render(request.Context(), writer); err != nil {
        http.Error(writer, err.Error(), http.StatusInternalServerError)
    }
}

What you provide

Configure the brand, navigation links, and page metadata, then pass in your content. Your application handles routes, permissions, and data.