Compress the images, PDFs, videos and audios stored on your site, locally or through cloud APIs, generate WebP copies, and let the web server transparently deliver the optimized versions instead of the originals. Your original files are never modified.

Image Compression

Optimize JPEG, PNG, GIF and SVG files locally (jpegoptim, optipng, pngquant, svgo, gifsicle) or through the TinyPNG, ShortPixel, Kraken.io and reSmush.it APIs.

WebP Generation

Create a lighter .webp sibling for every JPEG/PNG image. Browsers that support WebP receive it automatically; others keep getting the original format.

PDF Compression

Shrink PDF files with Ghostscript (screen / ebook / printer presets) or through the ConvertAPI cloud service.

Video & Audio

Re-encode videos (H.264/VP9, configurable CRF) and audios (configurable bitrate) with FFmpeg. Disabled by default because transcoding is CPU-intensive.

Non-Destructive

Optimized copies live in a dedicated mirror folder. Delete them at any time: the original files are served again instantly, with or without the add-on.

Built for Big Libraries

Chunked scanning and short processing steps keep memory usage low and never block your visitors, even with tens of thousands of files. Works with or without a queue worker.

How It Works

  1. Scan: the add-on indexes every optimizable file of your public storage into its own catalog (path, type, size).
  2. Optimize: each file is compressed by the engine you selected. When the result is smaller than the original (by at least the configured threshold), the optimized copy is saved into the mirror folder storage/app/public/_optimized/<same path>. For images, an optional .webp sibling is generated as well.
  3. Serve: rewrite rules added to your web server check, for every /storage/... request, whether an optimized copy (or a WebP variant, when the browser accepts it) exists. If yes, it is served; if not, the original file is served exactly as before.
Safety first: originals are never touched, the rewrite rules only fire when an optimized file actually exists on disk, and deactivating the add-on removes the rules. The site works identically with or without File Optimizer: it just gets lighter with it.

Use Cases

Speed Up an Existing Site

Years of uploads pile up. Scan the storage once, click “Optimize everything”, and let the add-on compress your whole media library in the background, then serve WebP to the ~97% of browsers that support it.

Improve Core Web Vitals & SEO

Smaller images mean faster LCP and better PageSpeed scores. The Vary: Accept header is set correctly so caches and CDNs keep working.

Reduce Bandwidth & Storage Costs

Image savings of 30–70% are common. The overview page tracks the exact number of bytes saved per file type.

Compress Heavy Documents

Scanned PDFs and brochures shrink dramatically with the Ghostscript ebook preset while staying perfectly readable on screen.

Requirements

  • LaraClassifier / JobClass v19.0.0 or later
  • PHP 8.3+, MySQL 8.0+
  • The public storage symlink (php artisan storage:link), standard on every install
  • Optional local binaries depending on the engines you enable:
    • Images: jpegoptim, optipng, pngquant, svgo, gifsicle
    • WebP: cwebp (or the Imagick / GD PHP extensions)
    • PDFs: gs (Ghostscript)
    • Videos & audios: ffmpeg
No binaries? No problem for images and PDFs. Images can be compressed by a cloud engine (TinyPNG, ShortPixel, Kraken.io, or reSmush.it, which needs no key at all) and PDFs by ConvertAPI, so only an API key is needed. And even without any image binary, WebP copies can still be generated through Imagick, GD or ConvertAPI. Video and audio compression, on the other hand, always requires ffmpeg on the server.

Installation

Step 1: Upload the add-on

Go to Admin panel → Extensions → Add-ons, click Upload add-on and drop the add-on's .zip file into the upload area (50 MB maximum). The archive is extracted into extensions/addons/fileoptimizer/ and File Optimizer appears in the list, deactivated.

Cannot upload from the browser? Unzip the archive on your computer and copy the add-on folder to extensions/addons/fileoptimizer/ over FTP or SSH: its addon.json file must sit directly inside that folder. Then open Admin panel → Extensions → Add-ons. The page scans extensions/addons/ every time it loads, so the add-on is listed straight away (the Sync button runs the same scan on demand).

Step 2: Activate the add-on

Click Activate on the File Optimizer card. It is a paid add-on, so a dialog asks for its purchase code, which is verified before anything else happens: an invalid code is rejected in the dialog and nothing is changed.

Once the code is accepted, activation runs in one pass: it creates the add-on's database tables (its migrations), registers its permissions, runs its seeders and publishes its public assets. Reload the page to see its new entry in the Add-ons section of the admin sidebar.

Step 3: Configure

Open Admin panel → File Optimizer from the Add-ons section of the sidebar and set the add-on up: see Quick Start (2 minutes).

Purchase Code (License Key)

File Optimizer is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate File Optimizer in Admin panel → Extensions → Add-ons.

Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.

Platform / Marketplace How you get the purchase code Where to find it again
bedigit.com Store
In-site purchase (Shop)
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. My Account → My Licenses on bedigit.com
Gumroad Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com
Envato Market
CodeCanyon
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. Envato account → Downloads → License certificate & purchase code
Check your spam folder. For both bedigit.com Store and Gumroad purchases, the purchase code is delivered by email. Automated license emails are very often filtered, so if the message is not in your inbox, look in your spam / junk folder before contacting support, and add our sender address to your contacts or allow list.

1. bedigit.com Store (in-site purchase)

  • As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
  • It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
  • The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
  • The matching invoice is under My Account → My Orders.

2. Gumroad

  • A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
  • The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
  • When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library → your purchase on gumroad.com.
  • Use the same email address on bedigit.com as on Gumroad: your keys are then linked to your account automatically and listed under My Account → My Licenses, even if you register after the purchase. You can also add a Gumroad key manually from My Account → My Gumroad Licenses.

3. Envato Market (CodeCanyon)

  • Envato purchase codes are issued and delivered by Envato Market, never emailed by us, so there is nothing to look for in your spam folder: you retrieve the code from your Envato account.
  • Log in to your Envato / CodeCanyon account, open the Downloads page, find the item, and choose License certificate & purchase code from the Download dropdown. The code is written in that certificate.
  • An Envato purchase code looks like 12345678-90ab-cdef-1234-567890abcdef (8-4-4-4-12 characters). It never changes, and renewing item support does not issue a new one.
  • Official Envato article: Where Is My Purchase Code?
Lost your purchase code? Search your mailbox (spam folder included) for “license” or “purchase code”, then check My Account → My Licenses on bedigit.com for Store and Gumroad purchases, or Downloads → License certificate on Envato. If it is still missing, open a ticket on our Help Center with your order number (Store), Gumroad sale ID or buyer email (Gumroad), or Envato username and item name (Envato).

Quick Start (2 minutes)

  1. Activate the add-on.
  2. Go to Admin panel → Add-ons → File Optimizer → Overview and click Scan storage.
  3. Click Optimize everything and keep the page open until the progress bar completes (or let your queue worker do the job).
  4. Open File Optimizer → Settings, go to the Rewrite rules tab and click Test the rules (live probe) to confirm the optimized copies are being served (on Nginx, paste the generated snippet into your server configuration first: see Nginx).

Admin: Overview Page

Admin panel → Add-ons → File Optimizer → Overview shows at a glance:

  • the total number of indexed files and the total space saved,
  • one card per file type (Images, PDFs, Videos, Audios) with its counters (total, optimized, pending, failed) its disk usage and savings, plus quick Browse and Optimize buttons,
  • the recent optimization runs and their results,
  • the live progress bar of a run currently in progress (it survives page reloads).

A paused badge on a card means optimization is disabled for that type in the settings.

The Overview and file pages require the admin.fileoptimizer.view permission; scanning, optimizing and deleting optimized copies require admin.fileoptimizer.optimize.

Scanning the Storage

The scanner walks the public storage and indexes every file whose extension matches an enabled type. It runs in short chunks (a few seconds each), so it can index tens of thousands of files without timeouts or memory spikes.

  • New files are added as Pending.
  • Modified files (size or date changed since the last scan) are reset to Pending and their stale optimized copies are deleted immediately, so outdated content is never served.
  • Deleted files are removed from the catalog along with their optimized copies.

Re-run the scan whenever you add or replace files. You can also automate it: see Console Commands.

Browsing Files

The sidebar offers one page per type: Images, PDFs, Videos and Audios. Each page lists the indexed files with a thumbnail (images), the path, original size, optimized size, savings percentage, WebP badge and status.

Filters & Search

The header of the list offers:

  • a search box matching the file path (updates the table as you type),
  • a status filter (Pending, Queued, Processing, Optimized, Skipped, Failed),
  • an extension filter listing the extensions actually present,
  • a Clear button resetting all filters.

Filtering refreshes only the table, without reloading the page.

File Actions

ButtonAction
⚡ OptimizeOptimizes this file right away and updates the row (also used to re-optimize after changing engines or levels).
🗑 Delete optimized copiesRemoves the optimized copy and the WebP sibling of this file. The original is served again instantly and the file returns to Pending.
File path linkOpens the file in a new tab (as served by the site, so you see the optimized version when the rules are active).
Statuses: Optimized = an optimized copy and/or a WebP sibling is being served · Skipped = the result was not smaller than the configured minimum savings, the original keeps being served · Failed = the engine returned an error (hover the badge to read it).

Optimizing Files

Single File

Click the lightning button on any row. The row updates in place with the new size, savings and status.

Bulk & Optimize All

  • Selection: tick the checkboxes (or the header checkbox) and click Optimize selected (n).
  • Whole type: click Optimize all <type> in the page header.
  • Everything: click Optimize everything on the Overview page.

Only files in Pending or Failed status are queued; types disabled in the settings are ignored.

Progress Bar

Every bulk run shows a progress bar with the processed / optimized / skipped / failed counters and the bytes saved so far, plus a Cancel button. Two processing modes exist (see General settings):

  • Browser-driven (default when no queue worker is configured): the page sends a short request every few seconds; each one processes a handful of files. Keep the page open until the bar completes.
  • Queue: one job per file is dispatched to your queue worker; the page only polls the progress. You can safely leave the page.

Cancelling a run releases the remaining files back to Pending.

Deleting Optimized Copies

To go back to the original files: use the row trash button for one file, or select several rows and click Delete optimized (n). The optimized and WebP copies are deleted from the mirror folder and the originals are served again immediately.

Settings: General

The settings page is at Admin panel → Add-ons → File Optimizer → Settings. It has six tabs: General, Images, PDFs, Videos, Audios and Rewrite rules. Opening it requires the admin.setting.view permission and saving it requires admin.setting.edit (the sidebar entry is shown to users who have admin.setting.view). The Processing card of the General tab holds:

SettingDescriptionDefault
Processing modeAutomatic uses the queue when the default queue connection (QUEUE_CONNECTION in .env) is not sync, and the browser-driven loop otherwise. Can be forced to Queue or Browser-driven.Automatic
Files per stepFiles processed per browser-driven step (1–25). Keep low on shared hosting.4
Time budget per stepSoft time limit (5–60 seconds) of one browser-driven step.20
Minimum savings (%)0–90. An optimized copy that does not save at least this percentage is discarded (Skipped) and the original keeps being served.2
Folders to scanRestrict the scan to specific folders (dynamic list: leave empty to scan the whole public storage). Accepts storage-relative folders, absolute server paths or document-root paths; everything is normalized automatically.empty
Folders to excludeFolders the scanner always skips (same accepted formats). The mirror folder (_optimized) and the add-on’s own folder (addons/fileoptimizer) are always excluded.empty

Settings: Images & WebP

SettingDescriptionDefault
Enable optimizationMaster switch for the image type.On
Compression engineLocal (spatie/image-optimizer chain) or the TinyPNG, ShortPixel, Kraken.io, reSmush.it APIs.Local
Optimization levelLossless (no quality loss), Balanced (barely perceptible loss) or Aggressive (maximum savings). Drives the jpegoptim/pngquant quality bounds and the API lossy modes.Balanced
Max file size for APIsFiles above this size (0–512 MB) are not sent to remote APIs. 0 removes the limit.32
Generate WebP copiesCreates a .webp sibling for JPEG/PNG images, served automatically to compatible browsers. Kept only when it is smaller than every other variant.On
WebP converterLocal (cwebp → Imagick → GD, first available) or ConvertAPI.Local
WebP quality1–100.80
Good to know: if no local image binary is installed but WebP generation is possible, images are still optimized in “WebP-only” mode instead of failing.

Settings: PDFs

SettingDescriptionDefault
Enable optimizationMaster switch for the PDF type.On
Compression engineLocal (Ghostscript) or ConvertAPI.Local
Compression presetScreen (72 dpi, maximum compression), Ebook (150 dpi, balanced) or Printer (300 dpi, high quality).Ebook

Settings: Videos

Video compression runs locally through FFmpeg and is disabled by default: transcoding is CPU-intensive and should be an explicit choice.

SettingDescriptionDefault
Enable optimizationMaster switch for the video type.Off
Quality (CRF)18–40. Lower = better quality and bigger files; 28 is a good balance.28
Encoding speed presetx264 preset from ultrafast to veryslow. Slower presets compress better.medium
Max heightDownscales larger videos to this height (never upscales). 0 keeps the resolution.0
Audio bitrateAAC/Opus bitrate of the audio track.128k

The optimized copy keeps the original container/extension (WebM stays WebM with VP9/Opus, MP4 stays MP4 with H.264/AAC), so the rewrite rules can serve it under the original URL.

Settings: Audios

Audio compression also runs locally through FFmpeg and is disabled by default.

SettingDescriptionDefault
Enable optimizationMaster switch for the audio type.Off
BitrateTarget bitrate (64k–320k). Lossless sources (WAV/FLAC) are only re-compressed within their own codec family, never converted to lossy.128k

Settings: Server Binaries

In the Server binaries card of the General tab, you can:

  • set an absolute path for each binary when it lives outside the system PATH (common with PHP-FPM),
  • click Check binaries to see which tools are installed and their version: a green Available or red Not found badge appears next to each field,
  • follow the Website & download link under each field to install a missing tool.

Typical installation on a Debian/Ubuntu server:

sudo apt-get install jpegoptim optipng pngquant gifsicle webp ghostscript ffmpeg
sudo npm install -g svgo
Tip: leave a field empty to use the command name from the system PATH.

Settings: API Credentials

Cloud engines only need an API key, entered in the API credentials card of the Images tab (a “Get your API key” link is shown under each field). The ConvertAPI secret entered there is also used by the PDF engine and the WebP converter when you select ConvertAPI:

ProviderCredentialsWhere to get them
TinyPNG / TinyJPGAPI keytinypng.com/developers (500 free images/month)
ShortPixelAPI keyshortpixel.com/api-settings
Kraken.ioAPI key + secretkraken.io/account/api-credentials
reSmush.itnone (free)5 MB max per image
ConvertAPISecretconvertapi.com/a/auth (PDF compression & WebP conversion)

The keys are stored in the database (settings table).

Serving Optimized Files: Rewrite Rules

The rewrite rules make the web server serve, for every request under /storage/:

  1. the WebP variant when the browser accepts WebP and a .webp sibling exists (with the correct Content-Type and a Vary: Accept header for caches),
  2. otherwise the optimized copy when it exists,
  3. otherwise the original file, exactly as before.

Manage everything from the Rewrite rules tab of the settings page: detected web server, rules status, install / remove buttons, live probe and ready-to-copy snippets.

Apache / LiteSpeed

The rules are written automatically into public/.htaccess, inside a clearly delimited block (# BEGIN FileOptimizer … # END FileOptimizer):

  • installed when the add-on is activated (unless the web server is detected as Nginx),
  • refreshed when the settings are saved, if the block is already installed,
  • removed when the add-on is deactivated or removed.

You can also install/remove the block manually with the buttons on the settings page.

Nginx

Nginx cannot be configured automatically from PHP. The settings page generates a ready-to-paste snippet (a map block for the http {} context and a location block for your server {} context). Paste it into your server configuration, run nginx -t and reload nginx.

Testing the Rules (Live Probe)

Click Test the rules (live probe): the add-on creates a temporary probe file plus an “optimized” copy, requests the public URL over HTTP, and reports which variant your web server actually returned, including whether the WebP variant is delivered. This works on any server type and is the definitive check that everything is wired correctly.

Note: the probe performs an HTTP request from the server to itself. On single-threaded development servers (php artisan serve) it will time out: that is expected; test on your real web server.

Console Commands

# Index the storage (same as the Scan button)
php artisan fileoptimizer:scan

# Optimize every pending file (all types, or one type, optionally capped)
php artisan fileoptimizer:optimize
php artisan fileoptimizer:optimize --type=image
php artisan fileoptimizer:optimize --type=pdf --limit=100

fileoptimizer:optimize processes the files inline, in the command itself, so it needs no queue worker. Typical cron automation (scan then optimize new files nightly):

0 3 * * * cd /path/to/your/site && php artisan fileoptimizer:scan && php artisan fileoptimizer:optimize >> /dev/null 2>&1

Queue Workers

When QUEUE_CONNECTION is set to database, redis, etc., and the processing mode is Automatic or Queue, bulk runs dispatch one job per file on the fileoptimizer queue. Make sure your worker listens to it:

php artisan queue:work --queue=fileoptimizer,default

No worker? Keep the Automatic mode: the browser-driven loop needs nothing but an open admin page.

Deactivation & Removal

  • Deactivate: the File Optimizer block is removed from public/.htaccess, so Apache/LiteSpeed serve the originals again. The catalog, settings and optimized copies are kept; re-activating reinstalls the rules (except on Nginx) and restores everything.
  • Remove: additionally drops the add-on tables, deletes the whole mirror folder (storage/app/public/_optimized/) and the add-on files. Your original files are untouched.
  • Nginx: the snippet you pasted into your server configuration is never removed automatically: delete it and reload Nginx after deactivating or removing the add-on.

Updating

An update only replaces the add-on's files. Its database tables and data, its settings, its activation state and its recorded purchase code are all kept, so do not deactivate or remove the add-on before updating it. Back up your database first all the same.

Method 1: Upload the new version (recommended)

  1. Download the latest .zip file of the add-on.
  2. Go to Admin panel → Extensions → Add-ons and click Upload add-on.
  3. Drop the .zip file into the upload area.
  4. Because File Optimizer is already installed, a prompt shows the installed version and the new one. Click Replace: the extensions/addons/fileoptimizer/ folder is swapped for the new files. Cancelling the prompt discards the upload.

Method 2: Replace the files by hand

  1. Over FTP or SSH, delete the extensions/addons/fileoptimizer/ folder and upload the new one in its place. Replace the whole folder rather than copying over it, so files dropped by the new version do not linger.
  2. Open Admin panel → Extensions → Add-ons: the page re-reads addon.json and the card shows the new version number.

After the files are replaced

New database tables or columns. When a new version adds some, create them by running php artisan migrate --force over SSH, or without SSH by clicking Deactivate then Activate on the add-on's card: activation runs every pending migration (and asks for the purchase code again). Your data is not touched either way.

If your installation caches its configuration or routes (php artisan config:cache, route:cache), run php artisan optimize:clear after the update.

Uninstallation

Switching an add-on off without losing anything is a deactivation: go to Admin panel → Extensions → Add-ons, click Deactivate on the File Optimizer card and confirm.

  • The add-on is no longer loaded: its routes, views, admin sidebar entry and front-end pages stop answering.
  • Its database tables and all the data they hold are kept, and its files stay under extensions/addons/fileoptimizer/. Nothing is deleted.
  • Its permissions and its recorded purchase code stay in the database. Only Remove deletes them.
  • Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.

Click Activate on the same card to switch it back on. As for a first activation, the purchase code is asked for and verified again; then any pending migrations run, the assets are republished, and the add-on picks up exactly where it left off.

Removing

Removing is permanent and destroys the add-on's data. The Remove button only appears on a deactivated add-on, so removal is always two steps:

  1. Deactivate File Optimizer (see Uninstallation).
  2. Click Remove on its card and confirm the prompt.

The admin panel then, in one pass:

  • runs the add-on's uninstall hook, if it ships one, while its code is still on disk;
  • revokes the permissions declared in its addon.json;
  • rolls back its migrations (this drops its database tables and every row they hold) and purges its entries from the migrations table, so a later reinstall migrates from scratch;
  • deletes its published assets: public/addons/fileoptimizer/, public/vendor/fileoptimizer/ and storage/app/public/addons/fileoptimizer/;
  • deletes the add-on directory extensions/addons/fileoptimizer/;
  • deletes its row in the addons table (the recorded purchase code goes with it) and clears the application cache.
This cannot be undone. Back up your database before removing an add-on whose data you may still need: installing it again later creates empty tables, not your old content, and asks for the purchase code again.

Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/fileoptimizer/. In that last case, give that user write permission on the directory and on its parent, then try again.

Deleting the folder over FTP or SSH is not equivalent: the add-on is only switched off, and its tables, its entries in the migrations table and its addons row are all left behind. Use Remove in the admin panel instead.

Troubleshooting

Files fail with “engine is not configured”

The selected engine needs binaries or credentials that are missing. Run Check binaries on the settings page, install the missing tools (links are provided under each field) or switch to a cloud engine and enter its API key.

The probe says optimized copies are NOT served

  • Apache: check that the block is installed (Settings → Rewrite rules), that mod_rewrite and AllowOverride All are enabled, and that public/.htaccess is writable.
  • Nginx: paste the generated snippet, run nginx -t, reload, probe again.

“Could not write public/.htaccess”

Fix the file permissions so PHP can write it (e.g. chown www-data public/.htaccess or chmod 664), then click Install the rules again.

Bulk run doesn’t progress in queue mode

Your worker is not running or not listening to the fileoptimizer queue. Start it (see Queue Workers) or switch the processing mode to Browser-driven and relaunch.

Most images end up “Skipped”

They are already well compressed: the result did not beat the Minimum savings threshold. That is by design (serving a barely-smaller copy is not worth it). Try the Aggressive level or enable WebP for extra savings.

A file changed but the old optimized version shows

Run a Scan: modified files are detected by size/date, their stale copies are deleted immediately and they are queued for re-optimization.

FAQ

Are my original files modified?

Never. Optimized copies live in a separate mirror folder; delete them at any time to serve the originals again.

What happens if I disable the add-on?

The rewrite rules are removed from public/.htaccess and the site serves the original files, exactly as before the add-on was installed. Nothing else changes. On Nginx, remove the snippet from your server configuration yourself.

Does it work on shared hosting?

Yes. The browser-driven mode needs no queue worker and no shell access; the reSmush.it engine even works without any binary or paid API. Only the .htaccess file must be writable for automatic rule installation.

Will WebP break browsers that don’t support it?

No. The WebP variant is only served when the browser explicitly advertises support via its Accept header; everyone else receives the original format. The Vary: Accept header keeps proxies and CDNs correct.

How much CPU does it use?

Work happens in short steps (a few files at a time) precisely so the front-end never slows down. Video/audio transcoding is heavier: that is why it is disabled by default and best run through a queue worker or cron at night.

File Optimizer v1.0.1 · LaraClassifier / JobClass Add-on · by BeDigit

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket