ctf0 / blazar
pre-render pages on the fly
Installs: 1 683
Dependents: 0
Suggesters: 0
Security: 0
Stars: 14
Watchers: 1
Forks: 5
Open Issues: 0
Requires
- php: ~7.0
- ctf0/package-changelog: ^1.0
- illuminate/support: ~5.4.0|~5.5.0|~5.6.0
- jaybizzle/laravel-crawler-detect: ^1.0
README
This project is abandoned due to impracticality, i would highly recommend to try using ServiceWorkers and here is a little article to get you started.
Blazar
Automate pre-rendering pages on the fly through utilizing puppeteer which runs in the background when needed without adding any overhead to the server nor to the user experience.
Installation
-
install puppeteer
-
composer require ctf0/blazar
-
(Laravel < 5.5) add the service provider to
config/app.php
'providers' => [ ctf0\Blazar\BlazarServiceProvider::class, ]
- publish the package assets
php artisan vendor:publish --provider="ctf0\Blazar\BlazarServiceProvider"
- add the middlewares to
app/Http/Kernel.php
protected $middlewareGroups = [ // ... \ctf0\Blazar\Middleware\Blazar::class, ]; protected $routeMiddleware = [ // ... 'dont-pre-render' => \ctf0\Blazar\Middleware\DontPreRender::class, ];
- the package use caching through Redis to store the rendered results, so make sure to check the docs for installation & configuration.
Config
config/blazar.php
return [ /* * puppeteer bin path */ 'puppeteer_path' => '', /* * puppeteer script path * * leave it empty to the use the one from the package */ 'script_path' => '', /* * prerender the page only if the url is being visited from a bot/crawler */ 'bots_only' => false, /* * log the url when its processed by puppeteer */ 'debug' => true, /** * clear user cache on logout */ 'clear_user_cache' => true ];
Usage
-
we use Queues to pre-render the visited pages in the background for more than one reason
- avoid latency when the page is being accessed for the first time.
- don't keep the user waiting in case
puppeteer
took long to render the page or when something goes wrong. - after
puppeteer
has finished rendering, the page is cached to optimize server load even further. - make your website SEO friendly, because instead of serving the normal pages that usually produce issues for crawlers, we are now serving the pre-renderd version. ReadMore
- even for websites with some traffic, we are still going to process each visited page without any problems.
# Render Pages Automatically
Atm in order to pre-render any page, it have to be visited first but if you want to make sure that all is working from day one, you can use the excellent package laravel-link-checker by Spatie
-
which by simply running
php artisan link-checker:run
you will- check which "url/link" on the website is not working.
- pre-render all pages at once.
# Flushing The Cache
- to clear the whole package cache, you can use
php artisan blazar:flush
or from within your app
Artisan::call('blazar:flush');
# Bots Only
we now use CrawlerDetect instead of relying on '?_escaped_fragment_'
if you decided to pre-render the pages for bots only, no need to the run the queue as the page will remain busy "stalled response" until rendered by puppeteer
, which happens on the fly.
however because we are caching the result, so this will only happen once per page.
also note that we are saving the page cache equal to the url so even if you switched off the bots_only
option, if the page is cached, we will always serve the cached result.
Notes
# Queues
the worker should only fires when a url is visited & if this url is not cached,
however if you have an unfinished old process, the queue will start processing pages on its own, so to fix that, simply restart the queue server beanstalkd, redis, etc...
# ex. using Homebrew
brew services restart beanstalkd
# Auth
as i dont know how to make laravel think that a page visited through puppeteer is the same as the current logged in user.
so trying to pre-render pages with auth
middleware will be cached as if the user was redirected to the home page or whatever you've set to redirectTo under
Constollers/Auth/LoginController.php
& Middleware/RedirectIfAuthenticated.php
so to solve that, simply add dont-pre-render
middleware to those routes and everything will work as expected.
also make sure to add the same middleware to any route that needs fresh csrf-token for each user "login, register, etc.." to avoid getting CSRF Token Mismatch
for other users trying to use those pages.