🤯 50% Off! 700+ courses, assessments, and books

First Look at Pagekit CMS – Clean, Extensible, Fast, But…

Bruno Skvorc

Pagekit hit version 1 recently, and as I’d been looking at personal blogging engines, I thought it’d only be fair to check it out. Granted, blogging is merely a subset of the functionality Pagekit can offer, but a good basic test-drive subset nonetheless.

Pagekit logo


Note: we’ll be using Homestead Improved for the environment in which to test things. All the commands, if any, will be listed with that in mind. Adapt for your own OS if necessary.

To install, we download and extract their archive, then point the web server to the newly created folder. Pagekit will immediately greet us with the installer screen.

Pagekit installation screen

After a short but incredibly smooth installation process, we land on the dashboard.

Pagekit dashboard

From the dashboard, we can access all other parts of the site like managing users, configuring new pages and routes, installing themes and extensions, deal with widgets, and more.

The permissions/roles subsystem is a bit limited in its default state, supporting only authenticated users, admins, and guests, but for a blog, which is what we’re testing here, that’s more than enough. If need be, more roles can be added in the Roles screen later.

Setting up a Pagekit Blog

Custom Pages

First things first, let’s set up an about page. If we head off to Site, and then Pages, we can set up a new page. Conveniently, Pagekit supports Markdown out of the box so we can use that to write the content.

Creating an about page

Immediately, the page (and the link leading to it) will appear in the home page of our site:

The about page rendered


To then set up a blog, we need the Blog extension installed. Luckily, it’s already there as a default and available from the main menu. A sample post is there, too: “Hello Pagekit”.

As a developer, I expect to write a lot of code snippets, so it’s imperative to see what that’ll look like in a post. Let’s modify the sample post and put in some technical content and an image or two. I’ll use a post previously published on SitePoint.

A published post, syntax not highlighted

It looks good – far better than one might expect a default theme to look – but only the inline code seems highlighted. The rest is plain. Let’s see how we can fix that.


Pagekit comes with an amazing marketplace which, while still quite empty, has the extensions/themes installation/download procedure down hard. It’s simple and easy to use, and relatively easy to develop for, without turning the developed packages into a horrid mess of spaghetti code.

The marketplace, conveniently, also already has a Highlight extension, obviously catering to developers from day one.

Syntax highlight extension in the Marketplace

The installation is simple, and, to every PHP developer’s delight, happens via Composer.

Composer installation of Highlight extension

Just refreshing the blog post’s render will show it in action – it’s automatically enabled!

Syntax highlighted code

Much better!

Custom Theme

The default theme, though, is a bit too standard. It’s beautiful, but as more and more people use Pagekit, the sites will begin to look alike, becoming a bit too recognizable – much like the “Bootstrap plague”. Let’s install another. The minimal theme looks fantastic, so let’s use that one.

In no more than a minute, the whole process is finished – the theme is installed and activated, and refreshing the site shows it.

Minimal theme installed and in use

Granted, it’s far from being as pretty as the demo, but one can hardly expect that when the content differs so much. Nothing some minor modifications can’t solve.

Pretty URLs

Pagekit URLs will default to ugly URLs with index.php in them on Apache servers without the rewrite module activated, and on Nginx. To get pretty URLs on Apache, the module needs to be enabled – refer to your server setup docs for that. In Nginx, the default setup from Homestead Improved will support pretty URLs (i.e. they will work) but Pagekit won’t enable them internally by default because it can’t detect that they’re on. To trick it, we can add a custom value into the server configuration:

fastcgi_param HTTP_MOD_REWRITE On;

Once we restart the server with sudo service nginx restart, this will make Pagekit think Apache’s rewrite mod is on, which in turn activates pretty URLs across the board. A sample full server configuration is below:

server {
    listen 80;
    listen 443 ssl;
    server_name pagekit.app;
    root "/home/vagrant/Code/pagekit";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/pagekit.app-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTP_MOD_REWRITE On;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;

    location ~ /\.ht {
        deny all;


Curiously, Pagekit goes against best practices and puts the entry point to the app (index.php) into the root folder instead of a public subfolder. On Nginx (and on Apache which doesn’t read local .htaccess files) this has severe security implications, as it allows anyone to access critical files (like pagekit.db – the site’s entire database) through the URL bar, by just typing in mypagekit.com/pagekit.db.

To get around this, we need to modify the server script further with a rather primitive line of code taken almost verbatim from their .htaccess file. Add the following just above location ~ \.php$ {:

location ~ /(composer.lock|pagekit.db|installed.json|composer.json|package.json|bower.json|CHANGELOG.md|README.md|gulpfile.js|webpack.config.js|pagekit) 
        deny all; 

403 error on forbidden files

It’s an extremely primitive and old-school solution, but it works. One can only hope the Pagekit team will move away from this folder structure some time in the near future.

Deploying a Pagekit site

Deploying a Pagekit site is as simple as uploading a static one, given that it defaults to SQLite for the database, and the database file is saved in the same folder. A full guide on doing this can be found here, using both Laravel Forge, and a raw DigitalOcean + Github approach, so take your pick!


At first glance, Pagekit seems like a nice alternative to the other CMS’s out there. The user interface is wonderful, their developer ecosystem incredibly friendly, and their plugin system well built, and built to last. It comes packed with some nifty default features like post duplication, Markdown, VueJS in the UI, sufficient default settings for both the site, and the blog/comments side of things, and everything that’s missing in the current settings can easily be added on with extensions.

It doesn’t come without its faults, though.

Firstly, the fact that its security depends on how well someone sets up the server means it’s not as cross-platform as it should be without heavy modifications – and we all know Nginx and Apache config files aren’t the most intuitive files to edit. Furthermore, the built-in PHP server can’t really be used for testing it properly, which limits the “play around” factor on certain machines, and definitely cripples the app in terms of being ready for a production-proof PHP native server, should it ever be developed. The Pagekit team should definitely throw in some PHP-side security checks, and move away from even trying to use .htaccess files.

Secondly, there’s no way to export the data from the database at this point. This makes porting the app to MySQL once a user is fed up with SQLite impractical, and limits the portability of the content – imagine setting everything up and writing the posts locally in SQLite, and then just uploading the data into a live app which uses MySQL instead.

Lastly, we could also list the inability to set a fully custom storage (currently only saves static files locally – though this can be done with an extension) and the short session lifetime (which can be worked around with a simple keepalive ping), but these are minor gripes indeed.

The marketplace is still quite empty, but I’ve no doubt it’ll fill up quickly once the ball starts rolling – and our upcoming tutorials are bound to help with that – but is it a “WordPress killer”? Not just yet. It certainly has more potential than pretenders like Ghost, but it needs to work on perfecting the MVP rather than removing the M from MVP for the sake of pleasing the crowd. We need a CMS with fewer features we can easily extend, but which works perfectly in its default state.

Have you tried Pagekit? How do you feel about it? Let us know in the comments!