Fix Pagination when Using Laravel Page Cache
Update [April 17, 2019]: I updated the original workaround (for Apache), which completely disabled caching for URLs containing a query string, with a similar ‘fix’ for NGINX. I will soon be adding have since added a second, real fix, too—one that fully enables caching, also for those URLs with a page
query parameter.
Note: this article’s all about Laravel websites that rely on the Laravel Page Cache package for page caching.
While it is perfectly possible to disable caching for URLs that contain a query string, such routes may still get served a previously cached page. We need to not only prevent URLs with a query string from being cached, but also prevent serving a cached page.
Luckily, completely disabling page caching for URLs sporting a query string is easy enough. It only requires slightly modified rewrite conditions in your site’s public/.htaccess
file—note the added %{QUERY_STRING}
conditions:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} ^/?$
RewriteCond %{DOCUMENT_ROOT}/page-cache/pc__index__pc.html -f
RewriteRule .? page-cache/pc__index__pc.html [L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}/page-cache%{REQUEST_URI}.html -f
RewriteRule . page-cache%{REQUEST_URI}.html [L]
This way, a cached page’ll only get served if the query string is absent.
In case your web server’s running NGINX rather than Apache, the following lines, which go inside a server
block, do the trick:
error_page 418 = @skip_cache;
recursive_error_pages on;
location = / {
if ($arg_page) {
return 418;
}
try_files /page-cache/pc__index__pc.html /index.php?$query_string;
}
location / {
if ($arg_page) {
return 418;
}
try_files $uri $uri/ /page-cache/$uri.html /index.php?$query_string;
}
location @skip_cache {
try_files $uri $uri/ /index.php?$query_string;
}
Note: you can’t have multiple try_files
directives inside a single location
block, and if
statements should only ever contain return …;
or rewrite … last;
.