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

Systatic Laravel Package

damcclean/systatic

Systatic is a PHP static site generator for building fast, content-driven websites with familiar templating and Markdown. It turns content and templates into deployable static HTML through a simple, developer-friendly workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Install in isolation first. Do not add this to your main Laravel app's composer.json on day one. Its Illuminate/View and Filesystem constraints will fight your framework's pinned versions, and you will either fail to resolve or silently downgrade shared packages. Start in a throwaway directory:

mkdir systatic-spike && cd systatic-spike
composer require damcclean/systatic

If Composer refuses to resolve on your PHP (test 8.2/8.3 explicitly), stop. The ROI case collapses at install, and there is no maintainer to escalate to.

Where to look first, in order:

  1. config/systatic.php — this is the contract. Read every key before writing a single template. Directory conventions (pages, collections, layouts), output paths, and any permalink/route rules live here.
  2. The package's default directory skeleton — if it ships one, mirror it exactly. The tool is opinionated; fighting the conventions costs more than adapting.
  3. A single example page → layout → build → output. That loop tells you more than any README.

First use case: one page, one layout, one build.

# assuming the documented artisan-style command
php artisan systatic:build
# or the standalone binary if present
./vendor/bin/systatic build

Create a Markdown page with frontmatter, a Blade layout that consumes it, run the build, and open the compiled HTML in dist/ (or whatever config/systatic.php names it). If you cannot get a page containing {{ $page->title }} and a loop over a collection rendering correctly by end of day one, that is your exit signal.

Implementation Patterns

Treat it as a build tool, not a framework. The mental model that makes day-to-day work sane: Markdown files are data, Blade files are functions, and the build command is render(). Nothing runs at request time.

Page / layout / collection split.

  • pages/ — one-off URLs (about, pricing, legal). Markdown + frontmatter, rendered through a layout.
  • collections/ — grouped content (blog posts, changelog entries, docs chapters). Loop these in an index template with @foreach.
  • layouts/ — the Blade shell. Put your entire design-system import here once, not per page.

Reuse your existing Blade components. This is the actual leverage: extract header, footer, card, callout, code-block into Blade components in the site repo and the marketing/docs output inherits your product's look for free. If your main app has a resources/views/components directory, mirror it.

Frontmatter as a schema. Decide the fields up front (title, date, description, slug, draft, order) and document them. Then write a validation step — even a 20-line PHP script in CI that parses the YAML block of every content file and asserts required keys — because the generator will not fail loudly on bad frontmatter. It will render null into your title.

Separate the asset pipeline. Systatic does not bundle CSS/JS or process images. Run Tailwind/Vite/whatever before the build and point it at the same output directory, or have the build copy a pre-built public/ into dist/. Decide this before templates multiply.

CI pattern that actually works:

# build on every PR, publish atomically
- composer install --no-dev --prefer-dist   # lockfile committed
- npm ci && npm run build                   # CSS/JS first
- php artisan systatic:build                # renders into dist/
- rsync -a --delete dist/ deploy:/var/www/site/  # atomic-ish swap

Publish to an ephemeral preview URL per PR so content reviewers see real HTML, not diffs of Markdown. This is the single highest-value piece of tooling you will build around the package.

Permalinks and routes. If config/systatic.php exposes route/permalink mapping, encode your URL policy there once (trailing slashes, dates in blog URLs) rather than fighting it per page. If it does not, plan to hand-roll a sitemap and be aware links are your responsibility.

Hand-roll what the package lacks. Sitemap, RSS, redirects, search index — the assessments note these are likely absent. All of them are cheap as post-build scripts or extra Blade templates that emit XML. Budget them explicitly rather than discovering them in week three.

Content migration is the cheap part. Markdown + frontmatter carries over from Jekyll/Hugo/Eleventy nearly untouched; only template syntax becomes Blade. Keep content as plain Markdown so the outbound cost stays low — Jigsaw uses Blade too, so escaping to a maintained generator is mostly a template port.

Gotchas and Tips

The package is unmaintained — assume fork-and-own. Zero stars, zero dependents, no release cadence, no security contact. Do not adopt it hoping for upstream fixes. The mitigating factor is that the surface you actually depend on (Blade, Illuminate view/filesystem, Symfony Finder, CommonMark) is maintained by others; the unmaintained part is the thin glue layer, which is small enough for one engineer to own.

Pin everything. Commit composer.lock, pin the PHP version in CI to match local exactly, and schedule a periodic build so silent dependency drift surfaces before a content author hits it. With no upstream releases, an unpinned lockfile is the primary way this breaks.

Full rebuilds only. Assume single-threaded, whole-site rendering. A few dozen pages is instant; low thousands will turn CI into the bottleneck and slow your editorial loop. If build time becomes the constraint, that — not a missing feature — is the trigger to migrate.

Silent failures are the default. Broken internal links, missing templates, bad YAML, and wrong field names surface as wrong output, not errors. Add to CI:

  • a link checker over dist/
  • HTML validation (or at minimum a "no empty <title>" assertion)
  • frontmatter schema validation

This is the highest-ROI defensive work you will do.

Fail the pipeline closed. A build that dies halfway can leave a truncated dist/ published — that takes the site down. Build into a temp directory and swap atomically, or gate the publish step on build exit code.

Local/CI drift. Because output is deterministic only if inputs match, lock the PHP version, the Composer platform config ("config": {"platform": {"php": "8.2.0"}}), and the Node version used for assets. Divergent HTML between a laptop and CI is a classic here.

Read config/systatic.php before debugging anything. Directory conventions, output path, and any collection registration live there. Most "why is my page missing" problems are a file in the wrong directory or a collection not registered — not a template bug.

Debug the compiled Blade, not just the template. Blade caches compiled views; a stale cache produces output that does not match your source. Clear the compiled view directory between debugging runs, and confirm whether the build itself clears it.

Watch the Markdown dependency. CommonMark version differences change rendering (tables, footnotes, HTML passthrough). Pin it and check the rendered HTML for a content page you know well after any composer update.

Extension points are Blade, not plugins. There is no documented plugin system. Your extension mechanism is: custom collections via config, custom output via post-build PHP scripts, and forking the package if you truly need to hook the render pipeline. Because the codebase is small, forking is a realistic option — plan a fork owner before you need one.

Frontmatter is a trap for non-engineers. YAML indentation, unquoted dates, and missing fields will all "succeed" and produce wrong pages. Before letting non-developers author content, put a schema validator in CI and a tiny authoring guide in the repo — you will not get support docs from upstream.

Write your own runbook in sprint one. There is no community to ask. Document the directory conventions, the frontmatter schema, the build/deploy commands, and the fork procedure while the knowledge is fresh. That document is the difference between a manageable dependency and an unmaintainable one.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager