• CMSnpm version

    • Overview
    • ContentBuilder
    • InviteUserForm
    • LoginForm
    • RenewPasswordForm
  • UInpm version

    • Overview
    • Accordion
    • AlertBubble
    • AnnouncementBar
    • Avatar
    • AvatarFileInput
    • Badge
    • Button
    • ButtonGroup
    • ButtonList
    • Calendar
    • Checkbox
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • Chip
    • ColorRadio
    • ColorRadioGroup
    • Combobox
    • DatePicker
    • DatePickerInput
    • DateRangePicker
    • DateRangePickerInput
    • DatetimePicker
    • DatetimePickerInput
    • Dialog
    • Dropdown
    • Dropzone
    • ErrorMessage
    • FileInput
    • FlashMessages
    • FormComponent
    • Icon
    • IconButton
    • ImageGallery
    • InfoBox
    • Input
    • Label
    • Layout
    • Lightbox
    • ListItem
    • Loader
    • Lozenge
    • Menu
    • Message
    • Modal
    • ✅ ModalDialog
    • ✅ ModalHeader
    • MultiCombobox
    • MultiSelect
    • Pagination
    • Paper
    • Popover
    • Radio
    • RadioGroup
    • RasterImage
    • Select
    • ✅ Tabs
    • TextInput
    • TextLink
    • Textarea
    • TimePicker
    • TimePickerInput
    • Toggle
    • Tooltip
    • Typography
  • Formnpm version

    • Overview
    • AvatarFileInput
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • ColorRadioGroup
    • Combobox
    • DatePickerInput
    • DateRangePickerInput
    • DatetimePickerInput
    • Dropzone
    • FileInput
    • Form
    • FormRenderer
    • GpsInput
    • MoneyInput
    • MultiCombobox
    • MultiSelect
    • NumberInput
    • PasswordInput
    • RadioGroup
    • Select
    • TextInput
    • Textarea
    • TimePickerInput
    • Toggle
  • DataGridnpm version

    • Overview
    • DataGrid
    • DataGridCustomExample
    • ExportButton
    • FilterList
    • Filters
    • FiltersButton
    • FulltextInput
    • HiddenColumns
    • HiddenColumnsButton
    • Pagination
    • RowCounts
    • RowsPerPageSelect
    • SelectedRowsToolbar
    • TableV2
    • ToolbarControl
    • ToolbarCustoms
    • ToolbarTabs
  • Wysiwygnpm version

    • Overview
  • Resizernpm version

    • Overview
  • Routernpm version

    • Overview
  • Corenpm version

    • Overview
  • Core-Reactnpm version

    • Overview
  • Stylesnpm version

    • Overview
  • Localizenpm version

    • Overview
  • Analyticsnpm version

    • Overview
  • Datepickernpm version

    • Overview
  • Icons-generatornpm version

    • Overview
  • Smart-addressnpm version

    • Overview
  • E2Enpm version

    • Overview
  • E2E-Playwrightnpm version

    • Overview

@uxf/resizer

npm

On-the-fly image resizing that serves the /generated/... URLs produced by resizerImageUrl (@uxf/core). It ships Next.js App Router route handlers for local development and a standalone Express server (uxf-resizer) for self-hosting. Resizing is done with sharp.

When to use

This package serves and generates resized images. It does not build image URLs — that is done client-side by resizerImageUrl from @uxf/core/utils/resizer, which encodes the resize parameters into a /generated/... path.

  • Production — a shared/global resizer service handles the /generated/... requests; you typically do not run this package there.
  • Local development — mount ProxyGET / StaticGET as Next.js route handlers so /generated/... URLs resolve during next dev.
  • Self-hosting — run the uxf-resizer CLI (Express server) driven by a config file.

Both entry points read the same URL segments (width, height, fit, position, background, trim, quality, target format) and pipe the source image through sharp. Generated files are cached on disk and re-served on subsequent requests.

Installation

yarn add @uxf/resizer --dev

The only runtime dependency is sharp. The standalone server additionally needs express, path-to-regexp, process, and yargs — they are not installed transitively, so add them yourself when you use the CLI:

yarn add @uxf/resizer express path-to-regexp process yargs --dev

Quick start

Next.js App Router route handlers for local development. Two handlers are exported:

  • ProxyGET — proxies uploaded images from the API and resizes them.
  • StaticGET — resizes static assets (public/ files and Next.js _next/static/media imports).

Folder structure:

src/
    app/
        generated/
            [...path]/
                route.ts    # ProxyGET  → uploaded images
            static/
                [...path]/
                    route.ts    # StaticGET → static images
// src/app/generated/[...path]/route.ts
import { ProxyGET as GET } from "@uxf/resizer";

export { GET };
// src/app/generated/static/[...path]/route.ts
import { StaticGET as GET } from "@uxf/resizer";

export { GET };

Both handlers read their upstream location from environment variables:

# .env.local
NEXT_PUBLIC_FRONTEND_URL=http://127.0.0.1:3000   # StaticGET source (Next.js static media)
NEXT_PUBLIC_API_URL=https://uxf.cz               # ProxyGET source (fetches <API_URL>/upload/...)

API

Exported from the package root (@uxf/resizer):

Export Signature Description
ProxyGET (request: Request) => Promise<Response> Next.js route handler. Matches /generated/:namespace/:p1/:p2/:filename_..._:extension.:toFormat, fetches the source from ${NEXT_PUBLIC_API_URL}/upload/:namespace/:p1/:p2/:filename.:extension, resizes, caches under the process CWD, and returns the image.
StaticGET (request: Request) => Promise<Response> Next.js route handler. Matches /generated/static/..._:quality/:version/:filename.:extension.:toFormat. Reads local public/:filename.:extension; for _next/static/media/* imports it fetches from ${NEXT_PUBLIC_FRONTEND_URL}.

Command-line server:

uxf-resizer

Starts an Express server on port 3000 that applies the routes from the configuration (see below). Requires the extra dependencies listed under Installation.

Route parameters

The URL segments understood by every route. They are produced by resizerImageUrl (@uxf/core) and mapped onto sharp options.

Parameter Values Default (falls back to sharp)
width number or x (auto) undefined (auto)
height number or x (auto) undefined (auto)
fit fit code (see below) cover
position position code (see below) sharp default (centre)
background hex (e.g. FFFFFF) or t (transparent) #<hex>
trim number (threshold) or nt (no trim) no trim
quality number (1–100) or x (auto) sharp default (avif: 50, others: 80)
toFormat webp, png, avif, jpg, svg jpg

svg is a passthrough — the source file is copied unchanged, without resizing.

Fit codes

  • cv: cover
  • f: fill
  • cn: contain
  • in: inside
  • out: outside

Position codes

  • a: attention
  • b: bottom
  • c: centre
  • e: entropy
  • l: left
  • lb: left bottom
  • lt: left top
  • r: right
  • rb: right bottom
  • rt: right top
  • t: top

Server configuration

The uxf-resizer CLI reads its config from .resizer-config.json in the working directory, or from the UXF_RESIZER_CONFIG environment variable (an inline JSON string, which takes precedence). Generated files are written to UXF_RESIZER_GENERATE_PATH (defaults to the process CWD).

The config is an array of { route, source } objects. route is a path-to-regexp pattern that captures the resize parameters; source is the original file location (a local path or an http(s) URL, which is fetched). source may reference any captured segment, including the domain as a parameter (e.g. https://:url/...).

[
    {
        "route": "/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)/:version/:filename(*).:extension.:toFormat",
        "source": "https://static.example.dev/:filename+.:extension"
    },
    {
        "route": "/generated/:namespace/:p1/:p2/:filename([a-f0-9\\-]+)_:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)_:extension.:toFormat",
        "source": "https://s3.example.dev/:namespace/:p1/:p2/:filename.:extension"
    }
]

resizerGetDefaultConfig(generatedFilesUrl, staticFilesUrl) from @uxf/core/utils/resizer returns exactly this two-route shape.

UXF Basic configuration (deprecated)

Deprecated — use the global resizer for all projects instead.

[
    {
        "route": "/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)/:version/:filename(*).:extension.:toFormat",
        "source": "https://uxf-base.uxf.dev/:filename+.:extension"
    },
    {
        "route": "/generated/:namespace/:p1/:p2/:filename([a-f0-9\\-]+)_:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)_:extension.:toFormat",
        "source": "https://s3.uxf.dev/${APP_NAME}-${APP_ENV}/:namespace/:p1/:p2/:filename.:extension"
    }
]

Gotchas

  • URLs are built elsewhere. Encode the parameters with resizerImageUrl from @uxf/core/utils/resizer; this package only serves the resulting paths.
  • CLI dependencies are not transitive. express, path-to-regexp, process, and yargs are dev dependencies of this package, so a consumer running uxf-resizer must install them explicitly.
  • Generated files are cached on disk. Once a variant exists under the output path it is served as-is; delete the cached file to force regeneration.
  • The server listens on a fixed port 3000 and an empty or invalid configuration throws on startup.
  • quality defaults to sharp's own defaults when set to x (avif ≈ 50, others ≈ 80). Values are expected in the 1–100 range.

Links

  • npm: @uxf/resizer
  • sharp documentation
  • URL builder: resizerImageUrl in @uxf/core/utils/resizer