Andy Hinkle

Andy Hinkle

Laravel Developer


July 21, 2024

Using Cloudflare Page Cache with Laravel

Cloudflare is a popular CDN that can cache your website's assets and pages to improve performance and reduce server load. In Laravel applications, you can use Cloudflare's page cache feature to cache entire pages and serve them directly from Cloudflare's edge servers.

We are going to assume that you have already registered and set up your domain with Cloudflare. If you haven't, you can follow the instructions on Cloudflare's website to set up your domain.

Step 1: Configure Cloudflare Page Rules

To enable page caching for your Laravel application, you need to create a page rule in Cloudflare that tells Cloudflare to cache all pages on your site.

Log in to your Cloudflare account and navigate to your domain's settings. Under the "Cache" tab, click on "Cache Rules":

Cloudflare Cache Rules

Click on "Create Rule" - Your Rule Name can be anything you want (I named mine "Cache All"). The rules should be set to the following:

  • IF..
  • When incoming requests match...
  • All Incoming Requests (checked)
  • Then...
  • Cache Eligibility: Cache Everything (checked)
  • (the rest of the settings can be left as default)
  • Place at: First

It should look like this:

Cloudflare Cache Rule Settings

Click "Save and Deploy" to save your changes.

Step 2: Configure Laravel to Work with Cloudflare Page Cache

By default, Laravel sends a "no-cache" header with every response, which tells Cloudflare not to cache the page. To enable Cloudflare page cache for your Laravel application, you need to modify the response headers to allow caching.

You can do this by adding the following middleware to your Laravel application:

        
1use Symfony\Component\HttpFoundation\Response;
2 
3class CachePageMiddleware
4{
5 public function handle($request, \Closure $next): Response
6 {
7 $response = $next($request);
8 
9 if ($this->shouldCacheResponse($request, $response)) {
10 $response->headers->add([
11 'Cache-Control' => 'max-age=1800, public',
12 ]);
13 }
14 
15 return $response;
16 }
17 
18 public function shouldCacheResponse($request, Response $response): bool
19 {
20 if (! app()->isProduction()) {
21 return false;
22 }
23 
24 if (auth()->check()) {
25 return false;
26 }
27 
28 if (! $request->isMethod('GET')) {
29 return false;
30 }
31 
32 if (! $response->isSuccessful()) {
33 return false;
34 }
35 
36 return true;
37 }
38}

Let's break down what this middleware does:

  • It does not cache responses in non-production environments.
  • It does not cache responses for authenticated users.
  • It only caches GET requests that return a successful response.
  • It sets the "Cache-Control" header to "max-age=1800" (30 minutes) for responses that should be cached.
  • If we don't meet the criteria, we don't cache the response and continue as normal.

Now you may modify the maximum age to your desired value. Cloudflare does not have a maximum cache time, but it's always a good idea to set a reasonable cache time -- I wouldn't recommend setting it to more than a few hours. Just remember that it must be in seconds.

Next, you need to register the middleware in your bootstrap/app.php file:

        
1use App\Http\Middleware\CachePageMiddleware;
2 
3return Application::configure(basePath: dirname(__DIR__))
4 ->withRouting(
5 web: __DIR__.'/../routes/web.php',
6 commands: __DIR__.'/../routes/console.php',
7 health: '/up',
8 )
9 ->withMiddleware(function (Middleware $middleware) {
10 $middleware->append(CachePageMiddleware::class);
11 })
12 ->withExceptions(function (Exceptions $exceptions) {
13 //
14 })->create();

This will add the CachePageMiddleware to the end of the middleware stack, so it will be executed on every request.

Your application is now configured to work with Cloudflare page cache. Cloudflare will cache your pages and serve them directly from its edge servers, improving performance and reducing server load.

You can test if Cloudflare is caching your pages by checking the cf-cache-status header in the response headers. If it says HIT then the page was served from Cloudflare's cache.

Keep in mind that Cloudflare page cache is not a replacement for Laravel's built-in caching mechanisms like Redis or Memcached. It's best used for static pages that don't change often. If you have dynamic content that changes frequently, you should use Laravel's built-in caching mechanisms instead.

That's it! You've successfully configured Cloudflare page cache with your Laravel application. Your site should now be faster and more responsive, with reduced server load.