Search by

gadya / cms

gadyamedia

A client-editable CMS for Laravel and Filament: live on-page editing, draft and publish, articles written with AI, SEO, forms, first-party analytics and team invitations.

v0.10.4 2026-09-22 04:09 UTC

README

Latest version Tests License

A client-editable CMS for Laravel and Filament, built around two ideas:

  • The admin is for structure. Pages, photos, the menu, the site's colours and type, articles, redirects, enquiries, and who may work on it, all live in a Filament panel.
  • The page is for content. The client opens the real page with the live editor switched on and edits the words and pictures in place, seeing exactly what a visitor will see.

Nothing either of those does reaches the public site until she presses Publish changes, and every publish is a revision she can restore.

It also counts its own visitors without Google or a cookie banner, keeps what people send through the site's forms, and - given an API key for any AI service - writes articles and search snippets in the business's own voice.

What you get

Pages One row each, with a type, a status, sections, a photo, a search snippet, and dates to appear and disappear.
Live editor @editable marks an element; the client edits it on the page. Text inline, prose in a side panel, photos from the library. One editor at a time, with a lock.
Draft and publish Every change is a draft until published. Preview links show a draft to someone with no account. Revisions restore any publish.
Photos Uploads resized, stripped of metadata, converted to WebP with responsive variants for srcset, optimised, with folders, tags, a focal point, alt text written by looking at the photo, and "used on". Never deletable while on a page.
Articles A writing screen with a findability score on every save. Categories, tags and their own archive pages, related articles, comments with a moderation queue, scheduled publishing.
Writing with AI Provider, model and key chosen in the panel, stored encrypted. A voice for the business. Whole drafts, rewrites, and search snippets from the page's own words. Any provider Laravel's AI SDK speaks.
SEO @cmsSeo renders every head tag with sensible fallbacks. A generated sitemap and robots file. A redirects table the client edits, with hit counts.
Forms Configured fields, a honeypot, an email with reply-to, an automatic reply written in the panel, an inbox with CSV download, and a mailing list that exports to any service.
Analytics First-party, no cookie, no address stored. Live panel over a websocket. CSV download, a weekly email.
Team Invitations by single-use link. Roles with abilities: a contributor writes articles but cannot publish a page. Nobody can remove themselves; the last administrator stays.
Search & speed Search Console queries and landing pages, Lighthouse scores from PageSpeed Insights, and a readiness score for AI assistants - llms.txt, AI-crawler rules, JSON-LD, Markdown on request.
Moving a site One zip with everything, photos included; import in place or replace.
What's on Events that sort themselves by date, stay listed until they end, and publish a calendar a phone can subscribe to.
Search The site's own search box - and a count of what people searched for and did not find.
Running it A trash with a thirty-day undo, duplicate anything, an activity log, a publish held until Friday at nine, coming-soon mode with a password link, and a broken-link list fixed with one click.
Look & feel Brand colours, a curated font list, the site's own logo in the panel.

Every one of those is a switch on the plugin, so a project takes only what it wants.

Requirements

PHP 8.3+, Laravel 13, Filament 5.

Install

composer require gadya/cms
php artisan gadya-cms:install
use Gadya\Cms\Filament\GadyaCmsPlugin;

$panel->login()->passwordReset()->plugins([GadyaCmsPlugin::make()]);
Gate::define('manage-content', fn (User $user): bool => $user->role !== 'customer');
Gate::define('manage-users', fn (User $user): bool => $user->role === 'admin');

Then, in a template:

@editableFor("pages.{$slug}")

<h1 @editable('heading')>{{ $page['heading'] }}</h1>
<p @editable('description', 'multiline')>{{ $page['description'] }}</p>
<img src="@siteImage($page['hero_image'])" @editable('hero_image', 'image')>

That is the whole idea. Installation has the rest of the setup.

Laravel Boost

The package ships a Boost guideline and three skills. In an application with laravel/boost, run php artisan boost:update --discover after installing:

  • gadya-cms-development teaches your agent to build with the CMS.
  • gadya-cms-content teaches it to help someone edit and publish.
  • gadya-cms-upgrade audits a site with gadya-cms:audit, upgrades it to the latest release, and switches on every feature it has not taken up yet. Ask: "Upgrade gadya/cms to the latest version and turn on everything, using the gadya-cms-upgrade skill." See Upgrading.

Try it

git clone https://github.com/gadyamedia/gadya-cms && cd gadya-cms
composer install && composer demo

A whole sample site on http://127.0.0.1:8000, admin at /admin (admin@example.com / password). See the demo.

The dashboard

Documentation

Taking only the parts you want

GadyaCmsPlugin::make()
    ->analytics(false)
    ->team(false)
    ->brand(false)
    ->blog(false)
    ->ai(false)
    ->redirects(false)
    ->forms(false)
    ->search(false)
    ->events(false)
    ->newsletter(false)
    ->profile(false)
    ->navigationGroups(content: 'Website', appearance: 'Design');

Testing

composer install
vendor/bin/phpunit

The package is tested on its own against a minimal host application, on PHP 8.3 and 8.4.

Credits

Built by Gadya Media. The analytics and the article writer are modelled on earlier first-party implementations of the same ideas.

License

MIT. See LICENSE.md.