PHPackages                             sushidev/fairu-statamic - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sushidev/fairu-statamic

ActiveStatamic-addon[Utility &amp; Helpers](/categories/utility)

sushidev/fairu-statamic
=======================

v3.1.0(2d ago)03.3k↑492.9%[5 PRs](https://github.com/sushidev-team/fairu-statamic-addon/pulls)VueCI passing

Since Mar 28Pushed 3w agoCompare

[ Source](https://github.com/sushidev-team/fairu-statamic-addon)[ Packagist](https://packagist.org/packages/sushidev/fairu-statamic)[ RSS](/packages/sushidev-fairu-statamic/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (17)Versions (71)Used By (0)

**This is the official [Fairu](https://fairu.app) addon for [Statamic](https://statamic.com).**

Fairu is your new powerful image and file proxy with the goal in mind to deliver your files in an optimized way.

Warning

**Upgrading from v2 to v3:** Fairu is now gated behind dedicated permissions. After upgrading, grant the new **Fairu Assets** permissions in each role under **Users → Roles** — otherwise non-super users lose Fairu access (nav hidden, action endpoints return 403). Already-attached assets in fields still render for everyone; only interactive actions are gated.

Permissions (all under the **Fairu Assets** group): `view`, `upload`, `edit`, `rename`, `move`, `delete` fairu assets. Independent — `view` is required for anything that needs the folder picker (move, browsing in fields), so grant it alongside any other action.

Features
========

[](#features)

This addon provides:

- Import all your assets into [fairu.app](https://fairu.app) using our commands
- Antlers tags making image handling smooth sailing.
- Fieldset to easily embed Fairu hosted files into your new or existing project

How to use
==========

[](#how-to-use)

You can install this addon via Composer:

```
composer require sushidev/fairu-statamic
```

Add env variables
-----------------

[](#add-env-variables)

Find your tenant ID in the [tenant settings](https://fairu.app/teams/settings) and [create an API key](https://fairu.app/api) for your application.

```
FAIRU_TENANT=[YOUR_TENANT_ID]
FAIRU_TENANT_SECRET=[YOUR_API_KEY_SECRET]
```

Import
------

[](#import)

On an existing project, you can run the following command which will automatically import all the connected assets into your fairu account. Depending on on the amount of files it might take some time.

```
php please fairu:setup

```

After the initial import, file paths will be transformed into the new Fairu-ID format dynamically.

Antlers tags
============

[](#antlers-tags)

There are several tags available to generate different code.

Metadata
--------

[](#metadata)

Note

The tags generally don't fetch metadata from the Fairu server and build the file path locally. Use the `fetchMeta` parameter to fetch the asset information from Fairu.

You can fetch metadata by passing `fetchMeta="true"` to the tags, which makes the metadata accessible.

### Lean vs. full fetch

[](#lean-vs-full-fetch)

The addon can fetch metadata in two modes:

ModeParameterEndpointReturns**Lean** *(default)*`fetchMeta="true"``POST /api/files/meta``id, name, width, height, focal_point, alt, caption, is_image, is_video, mime, active` — minimal, no licenses/copyrights/blocks, no N+1 scans.**Full**`fetchMeta="full"``POST /api/files/list`Full `File` resource including `licenses`, `copyrights`, `block` status, `hasValidLicense`, `amountInvalidLicenses`, etc. Use only when your template logic depends on that data.The lean endpoint is **~8× smaller** and issues **3–10× fewer SQL queries** on the Fairu backend. Unless you need license/block data at render time, stick with the default.

Fields accessible via `fetchMeta="true"`:

- name
- alt
- caption
- focal\_point (`x-y-zoom` e.g. `40-30-1`)
- focus\_css (e.g. `40% 30%`)
- width | height
- is\_image | is\_video | mime
- active

Use `fetchMeta="full"` when you additionally need `description`, `copyrights`, `licenses`, `block`, `size`, `fingerprint`, `extension`, or any other non-rendering metadata.

Automatic meta coalescing
-------------------------

[](#automatic-meta-coalescing)

When a page uses many `{{ fairu:image }}` / `{{ fairu:url ... fetchMeta="true" }}` tags — especially when they come from nested components, bards, or loops that you don't control up front — the addon automatically collapses every meta fetch on the page into a **single** batched API call.

### How it works

[](#how-it-works)

1. Each tag emits an opaque placeholder token instead of immediately fetching meta.
2. A response middleware (`CoalesceFairuMeta`) queues all ids while the view renders.
3. After Antlers finishes, it fires **one** `POST /api/files/meta` call for every unique id across the whole response.
4. The placeholders are replaced in-place with the final `` / URL output.

Result: a page with 15, 30, or 300 images issues exactly one meta round-trip per request, independent of template nesting.

### Enabling / disabling

[](#enabling--disabling)

Enabled by default. Toggle via environment variable:

```
FAIRU_COALESCE_META=false
```

…or in `config/statamic/fairu.php`:

```
'coalesce_meta' => env('FAIRU_COALESCE_META', true),
```

### Caveats

[](#caveats)

- **Do not wrap fairu tags in `{{ cache }}` blocks.** The placeholder would get cached without the corresponding queue entry, so subsequent cache-hit renders can't resolve it. Use Statamic's response-level static caching instead — the middleware runs *before* static caching stores, so the cached HTML contains the final output.
- **String operations on tag output** (e.g. `{{ fairu:url ... | upper }}`) will operate on the placeholder, not the URL. Rare, but worth noting.
- Only `text/html` responses are rewritten. JSON, streamed, and binary responses pass through untouched.
- Tags without `fetchMeta` or with an explicit `name` parameter render immediately and don't go through the coalescer — no change in behaviour.

### Requirements

[](#requirements)

The `POST /api/files/meta` endpoint is required on your Fairu backend for the default (lean) mode and for meta coalescing. It ships with `fairu-app` alongside this addon version. If you run an older Fairu deployment that doesn't expose the endpoint yet, set `FAIRU_COALESCE_META=false` and use `fetchMeta="full"` until the backend is updated.

Available parameters
--------------------

[](#available-parameters)

FieldDescriptionfairu:url:image:images**⁠id**The file ID**✓****✓****✓****✓****⁠name**Custom filename**✓****✓****✓****✓****alt**Custom alt**✓****✓****✓****⁠width**Resize image width**✓****✓****✓****⁠height**Resize image height**✓****✓****✓****⁠quality**Image quality (default: 90)**✓****✓****✓****⁠sources**Semicolon separated srcset entries**✓****✓****✓****ratio**Aspect ratio for sources**✓****✓****✓****⁠format**Convert image format**✓****✓****✓****fit**cover / contain the image**✓****✓****✓****⁠focal\_point**Focal point for cropping**✓****✓****✓****timestamp**Video thumbnail timestamp (HH:MM:SS.mmm)**✓****✓****✓****✓****fetchMeta**`"true"` for lean meta (default), `"full"` for full `File` resource, `"false"` to skip**✓****✓****✓****✓**{{ fairu }}
-----------

[](#-fairu-)

Get the file and get access to image properties.

```
{{ fairu id="ID" alt="Alt text" }}

{{ /fairu }}
```

{{ fairu:url }}
---------------

[](#-fairuurl-)

Get the URL of a file.

```
{{ fairu:url id="ID" name="filename.webp" }}

https://fairu.app/files/[UUID]/filename.webp
```

If you don't know the filename (e.g. for video files where the extension matters for browser playback), pass `fetchMeta="true"` to resolve the real filename from Fairu:

```
{{ fairu:url id="ID" fetchMeta="true" }}

https://fairu.app/files/[UUID]/hero.mp4
```

{{ fairu:image }}
-----------------

[](#-fairuimage-)

Generate a complete HTML image tag.

```
{{ fairu:image id="ID" width="800" height="600" class="my-image" alt="Image description" }}

```

{{ fairu:images }}
------------------

[](#-fairuimages-)

Generate multiple HTML image tags (see \[\[#{{ fairu image }}\]\])

```
{{ fairu:images ids="[IDS]" width="800" height="600" class="my-image" alt="Image description" }}

...
```

Responsive Images
-----------------

[](#responsive-images)

With most of our tags you have easy access to implementing responsive images using the native `srcset` and `sizes` properties to define when which source (version of the image) should be used. See [the mdn documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Responsive_images) for a great introduction into implementing responsive images.

### Implementation

[](#implementation)

The `sources` attribute provides a way to easily pass an array of widths, breakpoints and optionally heights to generate a `srcset` property that includes all listed sources.

This allows you to pass the sources property and use the calculated `srcset` property along with a fitting `sizes` to define which sources should be used when:

```
{{ fairu id="ID" sources="100,100w;512,512w" }}

{{ /fairu }}

```

### Formats

[](#formats)

Each pair consists of:

- A width value (in pixels) that defines the image width at that breakpoint
- A height value (in pixels) that defines the image height at that breakpoint **(optional)**
- A breakpoint value (with 'w' suffix) that corresponds to the viewport width

```
sources="[width1],[breakpoint1]w;[width2],[breakpoint2]w"

sources="[width1],[height1],[breakpoint1]w;[width2],[height2],[breakpoint2]w"

```

#### Ratio

[](#ratio)

If all sources should have the same aspect ratio, you can use the `ratio` attribute as a shortcut without height:

```
{{ fairu id="ID" sources="320,320w;480,800w;768,1200w;1200,1600w;1920,2400w" ratio="16/9" }}
```

This calculates all heights accordingly.

### The sizes attribute

[](#the-sizes-attribute)

The ⁠sizes attribute tells the browser how large the image will be displayed at different viewport widths. If not provided, it will be auto-generated based on the breakpoints in the ⁠sources parameter.

For a full-width responsive image, you can leave the sizes property empty or you can use:

```
sizes="100vw"

```

For more complex layouts, add media queries and a default or fallback value as last value:

```
sizes="(min-width: 1200px) 1200px, (min-width: 768px) 800px, 100vw"

```

Details
-------

[](#details)

For more information, visit the documentation at  to find out what else you can do with Fairu.

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance97

Actively maintained with recent releases

Popularity22

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 51.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

62

Last Release

2d ago

Major Versions

v1.10.8 → v2.0.02026-03-16

v2.6.2 → v3.0.02026-05-28

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4183575?v=4)[Rafael Issao](/maintainers/sushidev)[@sushidev](https://github.com/sushidev)

---

Top Contributors

[![Gitsack](https://avatars.githubusercontent.com/u/22915882?v=4)](https://github.com/Gitsack "Gitsack (153 commits)")[![leganz](https://avatars.githubusercontent.com/u/3373530?v=4)](https://github.com/leganz "leganz (81 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (61 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/sushidev-fairu-statamic/health.svg)

```
[![Health](https://phpackages.com/badges/sushidev-fairu-statamic/health.svg)](https://phpackages.com/packages/sushidev-fairu-statamic)
```

###  Alternatives

[livewire/flux

The official UI component library for Livewire.

9527.8M128](/packages/livewire-flux)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M194](/packages/laravel-ai)[statamic/seo-pro

68516.6k](/packages/statamic-seo-pro)[nativephp/mobile

NativePHP for Mobile

1.1k75.1k91](/packages/nativephp-mobile)[log1x/acf-composer

Create fields, blocks, option pages, and widgets using ACF Builder and Sage 10

504836.0k18](/packages/log1x-acf-composer)[nativephp/desktop

NativePHP for Desktop

39742.4k8](/packages/nativephp-desktop)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
