Pages
Static pages (About, Contact, Privacy Policy, Terms, etc.) are managed through PageCreate and PageEdit. Each page has a title, slug, meta description (with a live 155-character counter and overflow warning), rich body content, and an optional file attachment. The ManagesPageContent trait is shared across the Pages and Posts create/edit components — it provides slug auto-generation from the title (Str::slug()), the meta description character counter logic, and file upload helpers (addNewFile, removeNewFile).
Pages are looked up on the frontend by slug and locale via the Page::getCachedPage($slug, $locale) static method, which tries locale-matched records first, falls back to a PageTranslation record, and finally falls back to the English default — so every page has a graceful degradation path if a translation doesn't exist yet.
Blog Posts
Blog posts follow the same create/edit structure as pages. The PostCreate component handles featured image uploads directly via WithFileUploads — images are stored to a dedicated posts disk and referenced via a PostFile pivot model. The public blog index (Front\BlogIndex) uses WithPagination to paginate posts and loads the corresponding blog page metadata from the Page model by slug.
Home Page
The homepage is managed through its own dedicated model (Home) rather than the pages table, since it has a distinct layout and may need separate caching. The HomeIndex component lets the admin edit the homepage title, meta description, and body content. The public HomePage Livewire component calls Home::getCachedHomePage() on mount to serve a cache-warmed response.
Categories
The Categories component manages blog post categories via a full modal-based CRUD flow. Categories are a flat list — create, rename, and delete are all in-panel operations with confirmation gating on delete.