kraenkvisuell / kraenk-statamic-kit
Base setup for kraenkvisuell's eloquent-driven Statamic sites: database content, Bunny storage + CDN, static caching, shared commands and modifiers.
Package info
github.com/kraenkvisuell/kraenk-statamic-kit
pkg:composer/kraenkvisuell/kraenk-statamic-kit
Requires
- php: ^8.3
- statamic/cms: ^6.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Updatable Statamic starter kit for kraenkvisuell's eloquent-driven Statamic 6 sites. It carries the setup every site shares – content in the database (statamic/eloquent-driver, Postgres, uuid ids), asset container and Glide cache on Bunny Storage behind Bunny CDN, static caching, Horizon, Livewire-shipped Alpine, SEO Pro – the PHP that goes with it, and a complete theme as the starting point: the vollbild.film site (blueprints, fieldsets, Antlers views, Tailwind CSS, Alpine JS), to be made generic step by step. The conventions themselves live in ~/Code/coding-guidelines.
This repo is generated. Its source of truth is the package/ folder of a sandbox site plus that site's files; php please starter-kit:export writes this repo (see "Working on the kit"). Don't edit files here by hand – they are overwritten by the next export. The exception is .github/, which lives only here.
Two kinds of content
Package code (src/) stays a Composer dependency in every site (updatable: true) and is updated with composer update kraenkvisuell/kraenk-statamic-kit. Statamic autoloads it through the ServiceProvider (an AddonServiceProvider, namespace Kraenkvisuell\StatamicKit):
Console/Commands/–kit:init(sets a fresh site up: writes the site's slug – the name of the directory it lives in – into the env files (APP_URL=https://<slug>.testin.envand.env.example,DB_DATABASE=<slug>_testingandAPP_NAMEin.env.testing; the site's ownDB_DATABASEonly while it is still empty) and creates the<slug>_testingPostgreSQL database when it does not exist yet (where the login may not create databases it says so and carries on), asks whether the site is multisite (defaultat / with its routes under /de/…, so only the start page is /, andenat /en – the kit's default; the default site keeps Statamic's handle so an English single site needs no rename) or single-site (the default site alone without the language prefix: rewritesresources/sites.yaml, the collections' routes and site lists, the global sets' site lists, turnsmultisiteoff inconfig/statamic/system.phpand removespartials/navi/language-switch;--multisite/--single-siteskip the prompt), runs the demo pages, site settings, posts, projects, partners, SEO defaults and test user seeders; refuses to run withAPP_ENV=production; non-destructive and repeatable, more steps go at the end; outside local/staging add your login withphp please make:user --super;--forcerunsmigrate:freshfirst and only works withAPP_ENVlocal or staging),kit:copy-assets-to-bunny(--from,--to,--dry-run,--force),kit:fix-bard-list-items(--dry-run),kit:reset-postgres-keys(--dry-run). Listed byphp artisan list;php please listshows onlystatamic:commands.- The
kit:prefix plus the kebab-case class name is the convention for every command. Modifiers/–ensure_url,file_size(locale-aware viaNumber::fileSize).Database/Seeders/DemoPagesSeeder– demo content for a fresh site: start page (the only one with the intro), five main pages (Blog and Projekte carry the blog and projects listing sets), an area with three sub pages, footer pages Impressum/Datenschutz (contact is a jump to the contact section, not a page), localized into every site, placed in thepagestree and themain/footernavigations; the Blog and Projekte pages get theblogandprojectslisting sets (added when missing). Idempotent:php artisan db:seed --class="Kraenkvisuell\StatamicKit\Database\Seeders\DemoPagesSeeder".Database/Seeders/DemoPostsSeeder,DemoProjectsSeeder,DemoPartnersSeeder– three lorem ipsum blog posts (dated 30, 20 and 10 days back, one-sentence teaser), three projects (placed in the projects tree), onetext_mediaset each, and three partners without icon (the partners row shows dummy logos frompublic/placeholdersmeanwhile), localized into every site. Idempotent like the pages seeder;DemoSeederis the abstract base with the shared entry, lorem and tree helpers.Database/Seeders/SiteSettingsSeeder– lorem ipsum content for thesite_settingsglobals of the default site (contact data, address, social links, newsletter, video consent texts, the Datenschutz page as privacy page); the other sites inherit via the set's origins. Skipped when the variables hold data.Database/Seeders/TestUserSeeder– a super user for testing, test@kraenk.de / gogogoLilien1898!!!, seeded only whenAPP_ENVis local or staging; skipped when that email exists.Database/Seeders/SeoDefaultsSeeder– SEO Pro site defaults for a fresh site: lorem ipsum site name and description as placeholders,@seo:titleand@seo:permalinkas sources, the other sites inheriting from the default site, everything else empty. Only runs when no defaults are stored yet.StaticCaching/Invalidator– static cache invalidation along the site's content graph (listing pages, referencing entries, term carriers; globals, navigations and assets flush everything). Bound by the exportedconfig/statamic/static_caching.php, which also holds the graph underinvalidation.content_graph.ServiceProvideralso redirects the default site's language prefix (/de) to/on multisite setups, since the start page is/and only the other pages live under/de/….Http/Middleware/UseCdnClientIp– takes the visitor's IP from Bunny'sX-Real-IP. Not registered automatically: the site'sbootstrap/app.phphas to prepend it (see below), because it must run beforeTrustProxies.ServiceProvider::bootNumberLocale()–Number::useLocale()follows the site's locale (LocaleUpdated), so "210,6 KB" on/and "210.6 KB" on/en.
Exported files (export/, listed under export_paths in starter-kit.yaml) are copied into the new site once and are the site's own from then on:
- Infrastructure:
config/app.php(localede, fallbacken), eloquent-driver and users config (eloquent entries, trees, globals, terms, users and addon settings, so SEO Pro site defaults live in the database too; everything else file-based),config/statamic/seo-pro.php(redirects and 404 errors on the database driver), the migrations (uuid entries, uuid users with the blueprint columns, auth tables, addon settings, SEO Pro redirects and errors),app/Models/User.php(HasUuids),config/filesystems.phpwith thebunny-assetsandbunny-glide-cachedisks,config/statamic/assets.php(GLIDE_CACHE_DISK),config/statamic/static_caching.php(binds the kit's invalidator and describes the theme's content graph underinvalidation.content_graph),config/horizon.php(256 MB) +HorizonServiceProvider+bootstrap/providers.php,.env.examplewith all keys,.npmrc. - Content model: the collection, global-set and asset-container definitions of the theme (
content/**/*.yaml; entries, trees and global variables live in the database and are not part of the kit). - Tests:
phpunit.xml,.env.testingandtests/–php artisan testruns against the site's own<slug>_testingPostgreSQL database (the migrations switch the users table to uuid ids, which SQLite cannot do), with the Bunny disks faked intests/TestCase. - Theme:
resources/(blueprints, fieldsets, forms, views, css, js, roles,sites.yaml, SEO Pro settings, macros),public/placeholders/(placeholder image, video and partner logos shown while image/video/icon fields are empty),lang/,public/images/, and the Vite build (vite.config.js,package.json,package-lock.json; entriesresources/css/site.css,resources/js/site.js,resources/js/gallery.js).
dependencies are required into the site's composer.json at the versions the sandbox has (eloquent-driver, seo-pro, horizon, flysystem-aws-s3-v3, livewire, statamic-livewire; dev: pint, debugbar, error-solutions). The auto_alt_text module (default yes) adds el-schneider/statamic-auto-alt-text and its config.
Installing into a new site
statamic new my-site kraenkvisuell/kraenk-statamic-kit
# or, in an existing skeleton:
php please starter-kit:install kraenkvisuell/kraenk-statamic-kit
The package is on Packagist (kraenkvisuell/kraenk-statamic-kit), so a plain composer require works and no repositories entry is needed. Afterwards (also printed by the post-install hook):
-
.env:DB_CONNECTION=pgsql+ credentials,QUEUE_CONNECTION=redis,BUNNY_S3_*,BUNNY_PUBLIC_URL,GLIDE_CACHE_DISK=bunny-glide-cache,STATAMIC_PRO_ENABLED=true(the theme is multi-site de/en, seeresources/sites.yaml). -
php artisan migrate, thenphp artisan kit:init(env files from the directory name, single- or multisite, demo pages and navigations, site settings, blog posts, projects and partners, SEO Pro site defaults, the super user test@kraenk.de / gogogoLilien1898!!!). -
npm install && npm run build(ornpm run dev). -
Behind Bunny CDN, in
bootstrap/app.php:use Illuminate\Http\Request; use Kraenkvisuell\StatamicKit\Http\Middleware\UseCdnClientIp; ->withMiddleware(function (Middleware $middleware): void { $middleware->prepend(UseCdnClientIp::class); $middleware->trustProxies( at: '*', headers: Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO, ); })
-
Point the site's
CLAUDE.mdat@~/Code/coding-guidelines/CLAUDE.mdand keep only what is specific to the site. -
Static caching: set
STATAMIC_STATIC_CACHING_STRATEGY=halfin production; adaptinvalidation.content_graphinconfig/statamic/static_caching.phpwhen collections, sets or reference fields change.
Updating a site
composer update kraenkvisuell/kraenk-statamic-kit
updates the package code (src/). Exported files are not touched by updates – compare them with this repo's export/ folder by hand when something there changed.
Working on the kit
The kit is developed inside a sandbox site (a "dummy" Statamic site), never in this repo directly:
-
Set up the sandbox once. Create a Statamic site (or use an existing one), copy this repo's root files –
composer.json,starter-kit.yaml,StarterKitPostInstall.php,README.md,src/– into<sandbox>/package/, and require the package through a path repository in the sandbox'scomposer.json:"require": { "kraenkvisuell/kraenk-statamic-kit": "dev-main" }, "repositories": [ { "type": "path", "url": "package", "options": { "versions": { "kraenkvisuell/kraenk-statamic-kit": "dev-main" } } } ]
composer update kraenkvisuell/kraenk-statamic-kitlinksvendor/kraenkvisuell/kraenk-statamic-kittopackage/. Then install the exported files into the sandbox (php please starter-kit:install kraenkvisuell/kraenk-statamic-kit --localfrom a clone, or copyexport/over the sandbox), so the sandbox runs the theme. -
Edit in the sandbox. Code in
package/srcis live immediately (a new command or modifier only needs the file). Theme and config files are edited where they live in the sandbox (resources/,content/*.yaml,config/, …) – add new files toexport_pathsinpackage/starter-kit.yaml. Generic PHP goes intopackage/src; site-specific code stays inapp/and is not exported. -
Export and publish.
composer export # php please starter-kit:export ../kraenk-statamic-kit --clear, then restores .github from git cd ~/Code/kraenk-statamic-kit && git add -A && git commit -m "…" && git push
--clearempties the clone (except.git) before writing, so removed files disappear too.starter-kit.yamlis written with the dependency versions from the sandbox'scomposer.json. Packagist updates from GitHub (auto-update hook), so sites pick the change up withcomposer update kraenkvisuell/kraenk-statamic-kit(package code). Tag releases asvX.Y.Zand push the tag;.github/workflows/release.ymlthen creates the GitHub Release with generated notes..github/is the one folder maintained in this repo by hand:--clearremoves it on every export andcomposer exportrestores it withgit checkout -- .github.
Rules of thumb: whether a file belongs in src/ or in export_paths depends on who should be able to change it later – the kit (src/) or the site (export_paths). Anything in neither place is not part of the kit.