Hosting Laravel applications statically

January 11, 2024

Earlier this week Spatie released a new package called laravel-export, which bundles your Laravel application into a statically host-able website. To me, this is a great addition to the Laravel ecosystem, as it unlocks a whole new paradigm for hosting Laravel applications.

A method of hosting which would be perfect for websites like:

  • blogs
  • portfolios
  • landing pages

Which don't rely on making calls to a backend server, but display static information.

In this article we will be going over how to I used laravel-export to deploy the very blog you're reading right now; to Cloudflare Pages, Netlify and Vercel.

Initial setup

Before we can start deploying we need to install the package.

composer require spatie/laravel-export

We will also be publishing the config file so we can leverage the hooks.

php artisan vendor:publish --provider=Spatie\\Export\\ExportServiceProvider

The after hook depends on the hosting platform but the before hook is the same everywhere.

return [
'before' => [
'assets' => 'npm run build',
],
];

Running php artisan export right now will create a new dist folder with our bundled application. Now let's upload this folder to some hosting providers.

Cloudflare Pages

To upload our static site we will be using Cloudflare's CLI called wrangler.

npm install wrangler --save-dev

With wrangler installed we can run the following command to deploy our dist folder.

npx wrangler pages deploy dist

The first time you run this command you need to go through a few steps:

  1. You will be prompted to allow wrangler to make changes to your Cloudflare environment, click 'Allow' to continue.
  2. You will need to enter the name of your project, this will be used to create a hostname.
  3. Finally you will have to enter the production branch name, this doesn't matter very much since we are just uploading a folder but I used main.

Deployment done!

But if you were to visit the preview link generated by Cloudflare you might notice some things not working quite right, mainly compiled css/js and links. This is because the the laravel-export package uses the APP_URL environment value to generate the links and the locations of the compiled assets.

At this point you should however have a hostname provided by Cloudflare which you can find in their dashboard. Since I used boydbloemsma as my project name my hostname is boydbloemsma.pages.dev, we need to replace the old APP_URL value with this hostname. Then we can add the wrangler deploy command to the after hook and we are off to the races.

return [
'after' => [
'deploy' => 'npx wrangler pages deploy dist',
],
];

All we have to do now is run php artisan export and seconds later our application is deployed to Cloudflare.

Vercel

For Vercel we will be using their vercel CLI.

npm i -g vercel

We will need to login to Vercel so we run the following command.

vercel login

When this is done we can start deploying our dist folder.

vercel deploy dist --prod

The first time we run this command we need to create our project, I chose to name mine boydbloemsma again which provides me with the boydbloemsma.vercel.app hostname.

Don't forgot to update your APP_URL with this hostname.

Vercel then adds a .vercel folder in our dist folder to store the link between the folder and the project. We need to keep this .vercel folder because otherwise we will be prompted to link to a project everytime. Luckily the export-laravel package has a option called clean_before_export, changing this value to false makes sure the destination folder is not emptied before starting the export.

return [
'clean_before_export' => false,
];

We also have to update the after command.

return [
'after' => [
'deploy' => 'vercel deploy dist --prod',
],
];

And just like that running php artisan export deploys to Vercel.

Netlify

And last but not least, Netlify also has a CLI we will be using.

npm install netlify-cli -g

Similar to Vercel we also need to login here.

netlify login

Then we can deploy our folder.

netlify deploy --dir=dist --prod

Again we will be prompted to create a new project and we will be provided a hostname, boydbloemsma.netlify.app in this case.

Don't forgot to update your APP_URL with this hostname.

Update the after command.

return [
'after' => [
'deploy' => 'netlify deploy --dir=dist --prod',
],
];

Run php artisan export and we're live.

We've just deployed our Laravel website on three separate static hosting platforms!

Cons

While working on this article I did come across a few issues that you might run in to as well.

  • The @production blade tag doesn't work. This makes sense of course since we didn't update our .env to production, but it is something to remember.

  • Any preview links generated by the hosting platforms aren't really usable since they get their assets from the production hostname.