sayamaapps / kirby-tegaru
Resizes phone photos in the Kirby Panel before upload, dropping EXIF and GPS data.
Package info
github.com/sayamaapps/kirby-tegaru
Language:JavaScript
Type:kirby-plugin
pkg:composer/sayamaapps/kirby-tegaru
Requires
- php: ^8.2
- getkirby/composer-installer: ^1.2
Requires (Dev)
- ergebnis/composer-normalize: ^2.54
- getkirby/cms: ^5.0
- icanhazstring/composer-unused: ^0.9.7
- maglnet/composer-require-checker: ^4.0
- phpmd/phpmd: ^2.15
- phpunit/phpunit: 11.5.55
- vimeo/psalm: ^6.20
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-31 17:58:16 UTC
README
Lighter photo uploads from the phone into the Kirby CMS 5 Panel.
Versions: Kirby 5 · PHP 8.2 to 8.5 · MIT · Changes
Tegaru (手軽) is Japanese for "easy, light to handle". A 24-megapixel phone photo weighs 3–4 MB and often carries its GPS position, so Tegaru resizes it in the browser before the upload starts. The upload is typically about 1 MB, and the re-encoded file carries no location data.
Features
- Smaller uploads. Photos are resized in the browser (longest edge 2400 px, EXIF rotation applied).
- No location data. Re-encoded photos carry no EXIF or GPS block.
- Unique camera captures.
image.jpg(orimage.jpeg) is renamed tofoto-<local time>.jpgwhile active. - Upload from the empty field. A tap on an empty files field opens the device's picker (photo library and camera on a phone) instead of the list of files already there.
- Server safety net. Byte cap (15 MB), pixel cap (40 megapixels) and HEIC/HEIF files are rejected.
- Off by default. No cookies, no browser storage, no request to any other host.
- English and German. The Panel keeps Kirby's own upload dialog.
Requirements
- Kirby 5 and PHP 8.2 to 8.5.
- A browser with canvas support. Measured on iPhone Safari only; other browsers are untested.
Installation
Pick one of three ways. The plugin always ends up in site/plugins/tegaru/.
-
Composer. The installer puts the plugin into
site/plugins/tegaru/:composer require sayamaapps/kirby-tegaru
Add
/site/plugins/tegaru/to.gitignoreand deploy it likevendor/. -
ZIP. Download the source archive of a release from GitHub, unpack it and move the folder to
site/plugins/tegaru/. -
Git submodule. From the root of your site:
git submodule add https://github.com/sayamaapps/kirby-tegaru.git site/plugins/tegaru
Usage
-
Switch it on. Everything is off by default. In
site/config/config.php:return [ 'sayamaapps.tegaru.active' => true, ];
-
Set the photo blueprint. In
site/blueprints/files/<template>.yml:accept: mime: image/jpeg, image/png, image/webp create: width: 2400 height: 2400 format: jpg
- HEIC: listing
mimeinstead oftype: imagekeeps HEIC out of the picker. On iPhone Safari a library photo then arrives as a JPEG (verified on iPhone only). Tegaru never converts HEIC; with the plugin on, the server refuses it. createis Kirby's server-side resize. It covers uploads that skip the Panel script (API, server-side import) and photos the script leaves unchanged. Whether it removes metadata depends on Kirby's image driver (thumbs.driver), so do not rely on it to remove GPS. Keep it at the top level; underoptions:,createis a permission setting.
- HEIC: listing
-
Upload in the Panel. Each picked JPEG, PNG or WebP photo of at least
minBytesis decoded, rotated, resized and re-encoded in the browser; the upload button waits until the photos are ready. The Panel script reads its settings fromGET /api/tegaru/options, which needs a logged-in Panel user.While the plugin is on, a tap on an empty files field does what the field's Upload button does. The Select button still lists the files already there. A field without uploads (
uploads: false), disabled or full keeps Kirby's behaviour. Kirby logsPlugin is replacing "k-files-field"in the browser console. -
The server checks every new or replaced file.
file.create:beforeandfile.replace:beforereject files abovemaxUploadBytes, JPEG, PNG, GIF or WebP images abovemaxPixels, and HEIC/HEIF files, with a message in the site's language. The server never resizes.
Limits
- No server-side resizing by Tegaru; use
create:. - Only Panel uploads are changed. Files that come in through the API or a server-side import are not re-encoded.
- Metadata stays in photos Tegaru leaves unchanged: while the plugin is off, below
minBytes, not decodable in the browser, HEIC, GIF, AVIF, SVG or PDF, not smaller once re-encoded, WebP the browser cannot encode, settings unavailable, or not ready 20 seconds after they were picked. - Images only. Video and other media are not touched.
- Kirby's upload module is not a public API. If the wrapped functions are missing, Tegaru logs one
console.infoand changes nothing.
Options
Write each option as sayamaapps.tegaru.<name> in your site config, flat, as in step 1. null means "not set"; invalid values fall back to the default. The 1.x name tegaru.<name> still works as a fallback until 2.0, flat or nested, and is read without a warning. If both names are set, the new one wins. See Deprecations.
| Option | Type | Default | Example | Description |
|---|---|---|---|---|
active |
boolean | false |
'sayamaapps.tegaru.active' => true, |
Master switch. Off: the hooks let everything through, and the Panel script prepares no photo; the files field keeps Kirby's behaviour. |
maxEdge |
integer | 2400 |
'sayamaapps.tegaru.maxEdge' => 1920, |
Longest edge of the browser-side result, in px. |
quality |
number | 0.85 |
'sayamaapps.tegaru.quality' => 0.8, |
JPEG and WebP quality, 0.1–1.0. PNG has no quality setting. |
minBytes |
integer | 1048576 |
'sayamaapps.tegaru.minBytes' => 0, |
Files below this size (1 MB) are left alone in the browser. 0 processes every file. |
maxUploadBytes |
integer | 15728640 |
'sayamaapps.tegaru.maxUploadBytes' => 25165824, |
Server cap per file (15 MB). |
maxPixels |
integer | 40000000 |
'sayamaapps.tegaru.maxPixels' => 24000000, |
Server cap in pixels (width × height) for JPEG, PNG, GIF and WebP images (40 MP). |
language |
string | site default language | 'sayamaapps.tegaru.language' => 'de', |
en or de for server messages. Otherwise the site's default language, then Kirby's locale, then English. Panel messages follow the Panel's language. |
Deprecations
Deprecated in 1.x: they keep working and raise no notice. The docs and the code name the replacement.
| 1.x | Replacement | Notes |
|---|---|---|
'tegaru.<option>' in config.php |
'sayamaapps.tegaru.<option>' |
Still read as fallback. Rename the keys in your site config. |
tegaru_guard($kirby, $upload) |
Sayamaapps\Tegaru\Hooks::guard($kirby, $upload) |
Global function, kept as a wrapper. |
tegaru_i18n() |
Sayamaapps\Tegaru\Options::applyLanguage($kirby) |
Global function, kept as a wrapper. |
Tegaru\I18n::t($key, $values) |
none | Kept. It returns the same text from the tables and needs no Kirby app. |
Tegaru\Guard, Tegaru\I18n, Tegaru\Options |
Sayamaapps\Tegaru\Guard, Sayamaapps\Tegaru\I18n, Sayamaapps\Tegaru\Options |
Class aliases. instanceof and type hints keep working. |
Planned for 2.0
Breaking changes, not part of 1.x:
- The functions
tegaru_guard()andtegaru_i18n(),I18n::t()and theTegaru\class aliases are removed. - The test access of the Panel script (
window.tegaru) is removed.
Unchanged: the translation keys tegaru.<key>, the route GET /api/tegaru/options, the hook names, and the blueprint and Panel field names. From 1.x on, each message is also served as sayamaapps.tegaru.<key>, so a site can use the 2.0 spelling for its own translations; Tegaru itself reads tegaru.<key> until 2.0.
Privacy
Tegaru processes no visitor data. Nothing is stored in the browser, and nothing is sent to a third party. Re-encoded photos carry no EXIF or GPS data; files Tegaru leaves unchanged keep their metadata (see Limits).
Maintenance
Tests: composer test, and node --test tests/*.test.mjs for the Panel script. The Panel messages are Kirby translations under tegaru.<key>, registered in config/translations.php, so a site can override them. The server messages come from translations/ through I18n::text(), not from Kirby's translations: a refused upload gets its message without a Kirby app, as in 1.x. The lock file composer.lock is committed, and CI runs the lowest, the locked and the highest dependency versions. Issues and pull requests are welcome, without a support promise. Report security problems privately through GitHub's vulnerability reporting. Changes: CHANGELOG.md.
License
MIT, see LICENSE.md.