Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jigsaw Docs Template Laravel Package

tightenco/jigsaw-docs-template

A ready-made documentation site template for Jigsaw, the Laravel Blade-powered static site generator. It provides layouts, styling, navigation, and content structure so you can launch clean, fast docs without building the scaffolding from scratch.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a scaffold, not a dependency. You never composer require it — you instantiate it once and own the result forever. Internalize that before the first command, because every downstream decision (upgrades, CI, fork ownership) follows from it.

composer create-project tightenco/jigsaw-docs-template my-docs
cd my-docs
npm install
npm run dev            # template-provided: Vite dev server + asset pipeline
./vendor/bin/jigsaw serve   # or the composer script; serves the compiled site

The build needs PHP 8.x, Composer, Node (Vite 6-era, so Node 20+), and Tailwind. Pin all four now — a latest install is how this template first bites you.

Where to look first, in this order:

  1. config.php — the whole information architecture lives here: baseUrl, pretty, collections (each collection's source path, sort key, permalink), markdown options, and build destinations (build_local / build_production).
  2. source/_layouts/ — the master and docs layouts. This is where @yield('content'), @stack/@push and the sidebar slot are defined.
  3. source/_partials/ — nav, head, footer, admonitions. Your customization effort concentrates here, not in Markdown.
  4. source/docs/ (or whatever your collection path is) — one Markdown file per page, each with a front-matter contract.
  5. package.json + vite.config.js — confirms the asset story and whether the dev script watches content or only assets.

First use case — do this before you plan anything else: add a single page end to end.

---
title: Installing the SDK
order: 2
section: getting-started
extends: _layouts.docs
section: content
---

Save as source/docs/installing-the-sdk.md, confirm it appears in the sidebar, confirm $page->getUrl() resolves, then push build_production/ to a preview host. If that round-trip takes under 30 minutes you have a real build-time number and a real answer on hosting fit. If it takes a day, you have learned the template's shape cheaply instead of after a 40-page port.

Implementation Patterns

Let config.php drive navigation, not your Blade. Define collections once and read them everywhere:

'collections' => [
    'docs' => [
        'path' => 'docs',
        'sort' => 'order',
        'extends' => '_layouts.docs',
    ],
],

Then in source/_partials/nav.blade.php, build the sidebar from the collection variable Jigsaw injects for you:

@foreach ($docs->sortBy('order') as $item)
    <a href="{{ $item->getUrl() }}"
       class="{{ $page->getUrl() === $item->getUrl() ? 'font-semibold text-blue-600' : '' }}">
        {{ $item->title }}
    </a>
@endforeach

Grouping by section front matter is the cheapest way to get nested IA without hand-maintaining a nav file. The moment someone has to edit two places to add a page, the docs start rotting.

Compose with partials, not custom directives. Jigsaw compiles Markdown through Blade before rendering, so @include works inside .md files. That gives you reusable callouts without touching PHP:

{{-- source/_partials/callout.blade.php --}}
<div class="border-l-4 border-{{ $type === 'warning' ? 'amber-500' : 'blue-500' }} p-4">
    {{ $slot ?? '' }}
</div>
@include('_partials.callout', ['type' => 'warning'])
Breaking change in v2.
@endinclude

Push build-time work into bootstrap.php. This is the legitimate extension point: beforeBuild / afterBuild hooks are where a sitemap generator, a Pagefind search index, or a link checker belongs. Search is the single most common gap — bolt it on post-build rather than forking the theme.

Keep the day-to-day loop boring. Two terminals: Vite dev server for asset HMR, jigsaw serve for content. If the template's dev script doesn't watch Markdown, say so in the README rather than letting each writer discover it. Writers should be editing .md and refreshing, full stop.

CI is where this pattern pays off. Composer cache, npm cache, npm run build, jigsaw build production, publish build_production/. Wire a preview deploy per PR on day one — it converts "did my Markdown render?" into a link in the pull request and removes the fastest route to a broken docs site (merge-and-pray).

Handle redirects as a first-class artifact. Static output has no redirect server. If you change a permalink, you need a host-level rule (Netlify _redirects, Cloudflare rules, S3 routing rules) or a meta-refresh page. Generate both from a single source if URL churn is expected.

Gotchas and Tips

  • Blade parses your code samples. A {{ $variable }} inside a fenced block will be executed, not printed. Wrap examples in @verbatim … @endverbatim or prefix as @{{ }}. This is the number-one source of broken docs pages, and it only surfaces on the page that matters most.
  • baseUrl must match deployment exactly. A GitHub Pages project site needs /repo-name; get it wrong and every sidebar link 404s while the homepage looks perfect. Verify on the preview URL, not localhost.
  • pretty: true requires host support. Clean URLs are free on Netlify/Cloudflare; on S3 you need index-document configuration or the trailing-slash variants break. Confirm before you commit to a permalink scheme.
  • You will deploy build_local at least once. Put the destination in the deploy script and never type build_production/ by hand.
  • Sort order defaults are filename-based. If pages appear alphabetically, you're missing sort in the collection config or order in front matter. Set both, or set neither and accept it deliberately.
  • Every content change is a full rebuild. Fine at 50 pages, noticeable at 500, painful past ~1–2k. If you expect to grow, decide now whether you'll shard collections or accept it.
  • No search, no versioning, no i18n. This is scope, not a bug. Retrofitting any of the three is exactly the work that erases the time saved — if you need them soon, that's your re-evaluation trigger, not a backlog ticket.
  • Fork ownership is real and unnamed by default. Upstream releases are dependabot bumps; there is no supported upgrade path. Name an owner and write down the policy — even if the policy is "we will not sync upstream." Silent drift within a quarter is the normal outcome.
  • Don't commit vendor/, node_modules/, or build_*. Build in CI from a lockfile. Treat the whole build chain as a locked artifact, containerized, pinned.
  • Debug order when a page misbehaves: front matter valid YAML → extends/section keys match the layout's @yield → collection path matches the file's directory → permalink collision. Ninety percent of "it renders blank" is a section name that doesn't match the layout.
  • Add a 404.blade.php early. Static hosts fall back to it differently, and you'll want to point lost readers at the sidebar rather than a host default.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings