Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

A new website for Spatie: backend highlights

Original – by Freek Van der Herten – 7 minute read

For the first time in 4 years we completely redesigned our company website. We launched it today. The site is a simple Laravel app with some technical niceties. True to form we also open sourced the app, you can find the code in this repo on GitHub.

In this blogpost I'd like you to give you a tour behind the scenes.


GitHub integration

The past years we've been more and more involved in the open source community. We've created 100+ packages that have been downloaded for over 15 million times. On our website we dedicated an entire section to highlight our efforts. We list all our open source packages and projects.


We use the GitHub API to import most info on our public repositories to the database. The import is done by this console command which is scheduled to run daily.

GitHub doesn't have any info on download counts. That's why there is a seperate command that queries the Packagist API for the download numbers.

Getting involved in open source has a lot of benefits. We think it's important the lower the barrier of entry for those wanting to start contributing to open source. That's why we also list a few easy issues on our repos. These are perfect


Those easy issues, which are recognized by a specific label on an issue, are also imported via the GitHub API. Here's the command that handles the import of easy issues. Notice that any new issue also are automatically tweeted.

Our open source stuff wouldn't be as good if we don't get any help from the community. We are grateful for anyone we improved our code with a PR, fixed a typo for us, opened up an issue to ask us a question or report a problem. Symfony recently started with thanking random contributors on their site. We think this is a nice gesture so we've done that as well. Here's the command that imports a random contributor.


Displaying responsive images

All of our open source stuff falls under a specific license called postcardware. This means that if our code makes it into your production environment you're required to send us a postcard from your hometown. For us is kinda cool to get postcards from over the entire planet. We share every postcard we received on this dedicated page on our site.


We now have about 200 postcards displayed on that page. When I take a picture of a postcard with my phone the filesize is about 4 to 6 MB. If we were to use those images directly that the page size would be about 1GB.

You might think, just create a thumbnail version, but we went on step further. We used our own medialibrary to generate responsive images for those postcards. This means that if you visit the site via a small mobile device your browser will download smaller images than if you were working on a device with a larger monitor. We leverage the srcset attribute to accomplish this behaviour.

The first time you visit the postcards page you might have noticed that blurry versions of the postcards were displayed. This is a technique called progressive image loading. We inline a blurred svg version of the postcards in the page so that the browser can display that immediately. The browser will replace this with a real image when it gets downloaded.

Here's the markup that is generated by the medialibrary for a responsive image.

<img srcset="/images/medialibrary/539/responsive-images/open-source___medialibrary_original_2400_2605.jpg 2400w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_2007_2178.jpg 2007w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_1680_1823.jpg 1680w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_1405_1525.jpg 1405w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_1176_1276.jpg 1176w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_983_1066.jpg 983w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_823_893.jpg 823w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_688_746.jpg 688w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_576_625.jpg 576w, /images/medialibrary/539/responsive-images/open-source___medialibrary_original_482_523.jpg 482w, data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHg9IjAiCiB5PSIwIiB2aWV3Qm94PSIwIDAgMjQwMCAyNjA1Ij4KCTxpbWFnZSB3aWR0aD0iMjQwMCIgaGVpZ2h0PSIyNjA1IiB4bGluazpocmVmPSJkYXRhOmltYWdlL2pwZWc7YmFzZTY0LC85ai80QUFRU2taSlJnQUJBUUVBWUFCZ0FBRC8vZ0E3UTFKRlFWUlBVam9nWjJRdGFuQmxaeUIyTVM0d0lDaDFjMmx1WnlCSlNrY2dTbEJGUnlCMk9EQXBMQ0J4ZFdGc2FYUjVJRDBnT1RBSy85c0FRd0FEQWdJREFnSURBd01EQkFNREJBVUlCUVVFQkFVS0J3Y0dDQXdLREF3TENnc0xEUTRTRUEwT0VRNExDeEFXRUJFVEZCVVZGUXdQRnhnV0ZCZ1NGQlVVLzlzQVF3RURCQVFGQkFVSkJRVUpGQTBMRFJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVUvOEFBRVFnQUlnQWZBd0VSQUFJUkFRTVJBZi9FQUI4QUFBRUZBUUVCQVFFQkFBQUFBQUFBQUFBQkFnTUVCUVlIQ0FrS0MvL0VBTFVRQUFJQkF3TUNCQU1GQlFRRUFBQUJmUUVDQXdBRUVRVVNJVEZCQmhOUllRY2ljUlF5Z1pHaENDTkNzY0VWVXRId0pETmljb0lKQ2hZWEdCa2FKU1luS0NrcU5EVTJOemc1T2tORVJVWkhTRWxLVTFSVlZsZFlXVnBqWkdWbVoyaHBhbk4wZFhaM2VIbDZnNFNGaG9lSWlZcVNrNVNWbHBlWW1acWlvNlNscHFlb3FhcXlzN1MxdHJlNHVickN3OFRGeHNmSXljclMwOVRWMXRmWTJkcmg0dVBrNWVibjZPbnE4Zkx6OVBYMjkvajUrdi9FQUI4QkFBTUJBUUVCQVFFQkFRRUFBQUFBQUFBQkFnTUVCUVlIQ0FrS0MvL0VBTFVSQUFJQkFnUUVBd1FIQlFRRUFBRUNkd0FCQWdNUkJBVWhNUVlTUVZFSFlYRVRJaktCQ0JSQ2thR3h3UWtqTTFMd0ZXSnkwUW9XSkRUaEpmRVhHQmthSmljb0tTbzFOamM0T1RwRFJFVkdSMGhKU2xOVVZWWlhXRmxhWTJSbFptZG9hV3B6ZEhWMmQzaDVlb0tEaElXR2g0aUppcEtUbEpXV2w1aVptcUtqcEtXbXA2aXBxckt6dExXMnQ3aTV1c0xEeE1YR3g4akp5dExUMU5YVzE5aloydUxqNU9YbTUranA2dkx6OVBYMjkvajUrdi9hQUF3REFRQUNFUU1SQUQ4QSsyckh3NUtnUEJyMCtjOGZrWmFYdzI1Y0VxZUtibVhHTFJEZGVISFpqZ0dzSEk3SUt4V1BoaHovQUFtbGMzUjYxRG95Um43b3JEbU1lUWsvc2xNL2RGSE9QbEd0b3lNZnVpbHpGcFdHL3dCaUovZEZITU0zZkxyTW9YeTZBRTh1Z0E4dWdDU2dZVUFGQUJRQVVBRkFCUUFVQWYvWiI+Cgk8L2ltYWdlPgo8L3N2Zz4= 32w" sizes="1px" src="/images/medialibrary/539/open-source.jpg" width="2400">

Some more background info on how this all works can be found on the relevant page in medialibrary docs.

Avoiding cookies

We think cookie warnings are ugly and make the user experience worse. To avoid having to put such a warning on our site, we decided that our website shouldn't set any cookies at all. If you want to know how you can avoid setting any cookies in a laravel app, read this blogpost by Dieter Stinglhamber.


Our site does have a very small admin section to upload postcards. Because In order for the csrf protection to work on that form we need to set a session cookie. That's why we sneakily change the session driver when visiting that page.

Add postcard

Gathering visitor statistics

For most of our client sites we use Google Analytics. Because Google Analytics relies on setting cookies we can't used it on spatie.be. Instad of Google Analytics we use Matomo. It's a free, self hosted, open source tool that that can gather information about site visitors. It's easy to install on a server. In order to gather data about a site visitor a small JavaScript snippet is included on every page. It can operate without setting any cookies.


Fun fact: "matomo" is a Japanese words that can be translated as "honesty" or "deceny".

Improving performance by caching the response

Without any caching the app is already pretty snappy. On my MacBook Pro (from 2015) response times vary from 150 to 200ms. In my mind that's very acceptable but we can do better.

One of our popular package is laravel-responsecache. It can greatly speed up any laravel application by caching the entire response. If you need some more on how it works, read this blogpost. With that package installed response times average around 50ms.

We took a pramatic approach to invalidate the cache. Whenever something changes in the database we clear the responsecache. That happens in the base Eloquent model.

Closing thoughts

Our new site was principally designed by Willem Van Bockstal. During development everybody in our company contributed, making this a team effort. We're pretty happy with the results, but we won't stop here. In the coming months we'll add some more content and do some tweaks here and there.

Be sure to check out the guest post by my colleague Willem to know more about what's going on at the front end of our new site.

What do you think of our new site? Let us know in the comments below!

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.


What are your thoughts on "A new website for Spatie: backend highlights"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.