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

Cms Laravel Package

statamic/cms

Statamic is the flat-first, Laravel + Git powered CMS for building beautiful, easy to manage websites. This package is the core Composer library installed into an existing Laravel app, offering extensive documentation, community support, and official Pro support.

View on GitHub
Deep Wiki
Context7

Getting Started

Statamic is a flat-file CMS that lives inside a normal Laravel app. This repo is the core package, not a starter app — so there are two entry points:

  • New project: use the app skeleton (statamic/statamic) via the Statamic CLI, which pre-wires routes, config, and a default CP.
  • Existing Laravel app: composer require statamic/cms, then run the installer and publish config.
composer require statamic/cms
php please install          # or: php artisan statamic:install

Set at minimum in .env:

APP_URL=https://mysite.test
STATAMIC_LICENSE_KEY=        # required for Pro features

Where to look first (in order):

  1. config/statamic/ — stache.php, sites.php, static_caching.php, assets.php, repositories.php, api.php.
  2. content/ — everything an editor creates: content/collections/{collection}/{slug}.md with YAML front matter, content/trees/, content/globals/, content/taxonomies/.
  3. resources/blueprints/ — the YAML field definitions that drive both the CP and validation.
  4. resources/views/ — Antlers (.antlers.html) or Blade (.blade.php) templates.
  5. routes/web.php — Statamic registers front-end routes from your collections and any Route::statamic() calls.
  6. The core source: src/Entries, src/Fields, src/Tags, src/Http/Controllers/CP. Reading these is how you answer "can I do X?" faster than the docs.

First real use case — a blog:

# resources/blueprints/collections/blog/post.yaml
sections:
  main:
    fields:
      - handle: title
        field: { type: text, required: true }
      - handle: content
        field: { type: bard, validate: required }
// routes/web.php
Route::statamic('blog/{slug}', 'blog.show', ['layout' => 'layouts.blog']);
{{# resources/views/blog/index.antlers.html #}}
{{ collection:blog sort="date:desc" limit="10" paginate="true" as="posts" }}
  {{ posts }}
    <a href="{{ url }}">{{ title }}</a>
  {{ /posts }}
{{ /collection:blog }}
{{ paginate }}{{ links }}{{ /paginate }}

That loop — collection tag, blueprint-driven fields, URL from the entry — is the daily heartbeat of Statamic work.

Implementation Patterns

Querying content from PHP (not templates). The facades are the standard integration point with the rest of your Laravel code:

use Statamic\Facades\Entry;

$posts = Entry::query()
    ->where('collection', 'blog')
    ->whereStatus('published')     // 6.9 fixed this; prefer it over raw `published` checks
    ->orderByDesc('date')
    ->limit(5)
    ->get();

$entry = Entry::findByUri('/blog/hello-world');   // respects multisite + routing

Use this in controllers, API resources, sitemaps, mailables, Livewire components — anywhere Antlers is the wrong tool.

Antlers inside Blade. You rarely need to choose one template engine exclusively:

{{-- renders a tag and returns its string output --}}
{!! Statamic::tag('collection')->from('blog')->limit(5) !!}

Keep Antlers for content-shaped markup (loops over entries, conditionals on fields) and Blade for app layout, components, and anything with PHP logic.

Content modeling. Blueprints are the schema. Extract shared groups into resources/fieldsets/*.yaml and reuse via field: { type: group, fields: my_fieldset } or import. Sets in Bard/Replicator are where most editorial flexibility lives — define them once in a fieldset and reference them.

Events are the clean integration seam. Core fires Statamic\Events\* on every write (EntrySaved, EntryCreated, EntryDeleted, AssetSaved, FormSubmitted, UserSaved, …). Register listeners the Laravel way (in Laravel 11+ that's usually Event::listen() in a service provider or auto-discovery):

Event::listen(function (EntrySaved $event) {
    Cache::forget("entry:{$event->entry->id()}");
    // dispatch a job, ping a webhook, reindex search…
});

Prefer events over patching core or hooking repositories.

Building on top of it. Addons are the sanctioned extension path, and the generators are excellent:

php please make:addon vendor/thing
php please make:tag        # custom Antlers tag
php please make:modifier   # Antlers modifier
php please make:fieldtype  # PHP class + Vue CP component
php please make:widget

Fieldtypes are two-sided: a PHP class exposing render()/augmentation and a Vue component in the addon's resources/js. That's how most "we need a special editing experience" tickets get solved.

Forms and validation. Forms live in resources/forms/*.yaml with per-field validate rules; submissions are stored as files and exposed via Statamic\Facades\Form. Prefer a listener on FormSubmitted for CRM/email work over hacking the form controller, and configure honeypot/CSRF rather than writing your own.

Caching is the performance story. Two layers, both worth understanding early:

// config/statamic/static_caching.php  → strategy: 'full' | 'half' | null
php please static:warm
php please static:clear

Plus the in-template {{ cache }} tag for expensive partials. Static caching is the difference between a 40ms and 400ms page; wire it into your deploy script from day one.

Delivery APIs. REST is built in (/api/collections/blog/entries, config in config/statamic/api.php); GraphQL is Pro. Both respect the same blueprints, so headless front-ends get field names for free. For decoupled setups, this plus static caching is usually the whole architecture.

Multi-site. config/statamic/sites.php defines locales/domains; entries localize automatically. Use Entry::query()->where('site', $site) and {{ site:handle }} in templates. Test in at least two sites before shipping.

The Git workflow. Content is files, so content/ belongs in the repo (or a synced content repo). Day-to-day: editors work in the CP, developers review content diffs in PRs, and CI runs php please stache:clear + static:warm on deploy.

Gotchas and Tips

  • The Stache is a cache, not the source of truth. Every entry is indexed into storage/statamic/. If files change outside the CP (git pull, deploy, script writing markdown), indexes go stale. In dev, keep the watcher on; in production, always run php please stache:clear on deploy and consider warming it. php please stache:doctor diagnoses index weirdness.
  • Fields must be in the blueprint to be saved from the CP. Programmatic writes can push arbitrary keys, but the publish form strips anything not defined in a blueprint/fieldset. "My field isn't saving" is nearly always this.
  • Reserved handles. id, slug, date, published, updated_at, locale, origin, and anything _-prefixed are Statamic-owned. Name your fields around them — collisions produce confusing, silent behavior.
  • date drives status and ordering. published: true plus a future date means scheduled, not visible. Use whereStatus() rather than hand-rolling published + date comparisons (the 6.9 changelog shows how easy that logic is to get subtly wrong).
  • Antlers is parsed at render time. On hot paths it's measurably slower than Blade. Combine with static caching, avoid deep nesting of tags inside large loops, and don't put logic-heavy query params in a partial you render 200 times.
  • YAML front matter bites on colons and unquoted strings. title: Ship it: v2 breaks. Quote values containing : or starting with special characters, and prefer the CP/php please for content creation so formatting stays canonical.
  • Glide image caches are separate. After changing asset manipulation presets, run php please glide:clear; after moving containers, php please assets:.../reindex. Broken thumbnails are almost always a stale Glide cache or a changed container path.
  • Licensing and editions. This package's license is custom (LICENSE.md), not MIT — read it before assuming redistribution rights. Several capabilities (GraphQL, multi-site beyond limits, revisions) are Pro and gated by STATAMIC_LICENSE_KEY. Check the pricing page before designing around a feature.
  • Version pairing matters. 6.x tracks recent Laravel majors and PHP 8.2+; an old app on Laravel 10 needs 5.x. Read the upgrade guide between majors — the changelogs show a steady cadence of security hardening (SVG sanitization, endpoint authorization, path traversal) that you do want.
  • Don't hand-edit storage/statamic. Treat it as disposable. If you must, stop, clear, write the file, re-warm.
  • Testing content is a real trap. Addons and app tests that create entries pollute content/. Use Statamic's PreventsSavingStacheItemsToDisk testing concern, or point the app at a fixture content root in the test env.
  • Debugging workflow that works: php please support:details (now scrubbed of app name/URL) for bug reports, php artisan about for the environment, verbose logs in storage/logs, and the Statamic:: facade in Tinker for "why is this entry not appearing?" — Entry::findByUri() returning null tells you it's routing/status, not templating.
  • Extension points ranked by leverage: events → addon generators → custom tags/modifiers → fieldtypes → CP Vue components. Reach for the last one only when the PHP/Vue pair is genuinely necessary.
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.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json