Magazin website with 20.000+ pages

,

I work with Kirby since quite some time but I never used it for a content heavy project. I considering using it for a client with a magazin website of roughly 20.000+ pages (articles etc).

Does somebody have experiences with this already? What was or is your approach? I am happy to get all kind of inputs or a discussion going on.

This might be helpful: Remember this - Caching in Kirby

I think the biggest point is to not use a completely flat structure.

Like, don’t do:

â”” content
  └─ articles
     └─ ...20k articles here

But have something like

â”” content
  └─ articles
     ├─ 2024
     │  ├─ dec
     │  │  └─ ...45 articles here
     │  ├─ nov
     │  │  └─ ...30 articles here
     .
     .
     .

(splitting it up into year / month is just an example; it could be anything.)
This way the router should remain fast even without cache.

If you need search (you probably do), I’ve had good results by creating an index in a sqlite db. You would then index that via page hooks.

Snippet from a plugin in a project:

    'hooks' => [
        'page.create:after' => $pageHandler = include __DIR__ . '/config/hooks/pageAfter.php',
        'page.update:after' => $pageHandler,
        'page.changeTitle:after' => $pageHandler,
        'page.changeSlug:after' => $pageHandler,
        'page.changeStatus:after' => $pageHandler,
        'page.delete:after' => $pageHandler,
        // ...
    ],
    // somewhere in 'pluginfolder/config/hooks/pageAfter.php'
    if($p->intendedTemplate()->name() === 'article') {
        if(in_array($event->action(), [
            'update',
            'create',
            'changeTitle',
            'changeSlug',
            'changeStatus',
        ])) {
            if($p->isPublished() && $p->parents()->findBy('status', 'draft') === null)  {
                ArticleIndex::indexArticle($p);
            }
        } else if($event->action() === 'delete') {
            ArticleIndex::removeArticle($p);
        }
    }

ArticleIndex is then a class managing the sqlite file, but you could of course also hook up another index like algolia, etc. If possible the index should contains all information you need to display search results snippets, otherwise you’d need to lookup each individual matching article by its uuid (not that bad, but neither particularly fast). Just make sure to keep the content folder the “single source of truth”. The index should be volatile.

For the panel you would then probably also want to extend the default search: Panel search | Kirby CMS to exclude the articles from it and instead add your own from the index.

And that’s pretty much it, I think.
Of course if you’re able to cache the most often hit pages (homepage with the latest articles?), that’s better.

1 Like

consider setting the num in the blueprint to the date to avoid mass renaming when the sorting of pages changes.

1 Like