railway-image-service
v0.1.6
Published
JavaScript and React packages for the railway-image-service Railway template
Downloads
105
Maintainers
Readme
Railway Image Service
Integrating with your image service is easier than ever with these React components, hooks, and Node.js client.
Installation
npm install jotai railway-image-serviceExamples
Astro site
Next.js site
Node SDK
ImageServiceClient
A constructor that creates a Node client for your image service.
Options
| Name | Type | Required? | Description |
| -------------------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| url | string | Yes | The base URL of your image service. |
| secretKey | string | Yes | The SECRET_KEY of your image service. |
| signatureSecretKey | string | No | The SIGNATURE_SECRET_KEY of your image service. If provided URLs can be signed locally without making a network request. |
ImageServiceClient.put()
Create or overwrite a file in blob storage.
Arguments
| Name | Type | Required? | Description |
| --------- | ----------------------------------------- | --------- | ------------------------------------------------ |
| key | string | Yes | The key to use in blob storage. |
| content | ReadableStream \| Buffer \| ArrayBuffer | Yes | The contents of the file to put in blob storage. |
Returns
A Response object.
ImageServiceClient.get()
Get a file from blob storage.
Arguments
| Name | Type | Required? | Description |
| ----- | -------- | --------- | --------------------------------- |
| key | string | Yes | The key to get from blob storage. |
Returns
A Response object.
ImageServiceClient.delete()
Delete a file in blob storage.
Arguments
| Name | Type | Required? | Description |
| ----- | -------- | --------- | ------------------------------------ |
| key | string | Yes | The key to delete from blob storage. |
Returns
A Response object.
ImageServiceClient.list()
List keys in blob storage.
Options
| Name | Type | Required? | Description |
| ------------ | -------- | --------- | --------------------------------------------------- |
| prefix | string | No | A prefix to filter keys by e.g. path/to/. |
| limit | number | No | The maximum number of keys to return. |
| startingAt | string | No | The key to start listing from. Used for pagination. |
Returns
A list result object
export type ListResult = {
/** The keys of the files */
keys: string[];
/** A URL to the next page of results */
nextPage?: string;
/** Whether or not there are more results */
hasMore: boolean;
};ImageServiceClient.sign()
Get a signed URL for a path.
Arguments
| Name | Type | Required? | Description |
| ------ | -------- | --------- | --------------------------------- |
| path | string | Yes | The path to get a signed URL for. |
Returns
A signed URL for the given path.
imageUrlBuilder()
Creates a fluent builder for constructing image transformation URLs. Supports chaining of operations for resizing, cropping, filtering, and other image manipulations.
Arguments
| Name | Type | Required? | Description |
| -------- | -------------------- | --------- | ---------------------------------------------------- |
| client | ImageServiceClient | Yes | The image service client instance used to sign URLs. |
Returns
An ImageUrlBuilder instance that supports method chaining.
Examples
import {
ImageServiceClient,
imageUrlBuilder,
} from "railway-image-service/server";
const client = new ImageServiceClient({
url: process.env.IMAGE_SERVICE_URL,
secretKey: process.env.IMAGE_SERVICE_SECRET_KEY,
signatureSecretKey: process.env.IMAGE_SERVICE_SIGNATURE_SECRET_KEY,
});
const builder = imageUrlBuilder(client);
// Basic image resize
const url = builder.url("https://github.com/railwayapp.png").size(48).build();
// Avatar generation
const url = builder.avatar(48, { quality: 90 }).build();
// Complex transformation
const url = builder
.key("my-image-key.jpg")
.size(1200, 800)
.fit("cover")
.trim()
.filter({
quality: 85,
brightness: 10,
format: "webp",
})
.build();
// Smart cropping with focal point
const url = builder
.url("https://example.com/portrait.jpg")
.size(400, 400)
.smart()
.filter({
focal: "300,400",
format: "jpeg",
quality: 90,
})
.build();
// Sign the URL remotely
const url = await builder
.key("my-image-key.jpg")
.size(1200, 800)
.fit("cover")
.trim()
.filter({
quality: 85,
brightness: 10,
format: "webp",
});Image Source Methods
.key(blobKey)
Sets the image source using a blob storage key.
| Name | Type | Required? | Description |
| --------- | -------- | --------- | -------------------------------------- |
| blobKey | string | Yes | The storage key identifying the image. |
.url(httpUrl)
Sets the image source using a URL.
| Name | Type | Required? | Description |
| --------- | -------- | --------- | ---------------------------- |
| httpUrl | string | Yes | The URL of the source image. |
Avatar generation
.avatar(size, filters)
Applies optimized image filters and transformations for avatar images. Automatically enables smart cropping, cover fitting, and metadata stripping.
| Name | Type | Required? | Description |
| --------- | -------------- | --------- | --------------------------------------------- |
| size | number | Yes | Target size for the avatar (width and height) |
| filters | ImageFilters | Yes | Additional filter settings to apply |
Default Settings
fit:"cover"smart:trueupscale:truequality:80strip_exif:truestrip_metadata:truestrip_icc:true
Dimension Methods
.width(value)
Sets the target width of the output image.
| Name | Type | Required? | Description |
| ------- | -------- | --------- | ---------------- |
| value | number | Yes | Width in pixels. |
.height(value)
Sets the target height of the output image.
| Name | Type | Required? | Description |
| ------- | -------- | --------- | ----------------- |
| value | number | Yes | Height in pixels. |
.size(width, height?)
Sets both width and height of the output image.
| Name | Type | Required? | Description |
| -------- | -------- | --------- | ----------------------------------------------- |
| width | number | Yes | Width in pixels. |
| height | number | No | Height in pixels. Defaults to width if omitted. |
Transform Methods
.fit(value)
Sets the fit mode for image resizing.
| Name | Type | Required? | Description |
| ------- | ---------- | --------- | -------------------- |
| value | ImageFit | Yes | The fit mode to use. |
ImageFit Options
"cover": Scales to fill the entire box, cropping if necessary"contain": Scales to fit within the box while maintaining aspect ratio"stretch": Stretches or compresses to exactly fill the box"contain-stretch": Combines contain and stretch modes
.flip(direction)
Flips the image horizontally, vertically, or both.
| Name | Type | Required? | Description |
| ----------- | -------------------------------------- | --------- | ---------------------- |
| direction | "horizontal" \| "vertical" \| "both" | Yes | The direction to flip. |
.crop(x, y, width, height)
Crops the image to a specified region.
| Name | Type | Required? | Description |
| -------- | ------------------ | --------- | ----------------------------------------------- |
| x | number \| string | Yes | Left coordinate (pixels or percentage with '%') |
| y | number \| string | Yes | Top coordinate (pixels or percentage with '%') |
| width | number \| string | Yes | Width of crop (pixels or percentage with '%') |
| height | number \| string | Yes | Height of crop (pixels or percentage with '%') |
.padding(left, top, right, bottom)
Adds padding around the image.
| Name | Type | Required? | Description |
| -------- | -------- | --------- | ------------------------ |
| left | number | Yes | Left padding in pixels |
| top | number | Yes | Top padding in pixels |
| right | number | Yes | Right padding in pixels |
| bottom | number | Yes | Bottom padding in pixels |
.trim(enable?)
Enables trim mode to remove surrounding space.
| Name | Type | Required? | Description |
| -------- | --------- | --------- | ------------------------------------- |
| enable | boolean | No | Whether to enable trim. Default: true |
.smart(enable?)
Enables smart detection of focal points for cropping.
| Name | Type | Required? | Description |
| -------- | --------- | --------- | ------------------------------------------------ |
| enable | boolean | No | Whether to enable smart detection. Default: true |
.align(horizontal?, vertical?)
Sets the alignment for cropping and fitting operations.
| Name | Type | Required? | Description |
| ------------ | ------------------------------- | --------- | -------------------- |
| horizontal | "left" \| "center" \| "right" | No | Horizontal alignment |
| vertical | "top" \| "middle" \| "bottom" | No | Vertical alignment |
Filter Methods
.filter(filters)
Applies image filters like blur, brightness, contrast, etc.
| Name | Type | Required? | Description |
| --------- | -------------- | --------- | --------------------------------- |
| filters | ImageFilters | Yes | Object containing filter settings |
ImageFilters Options
| Name | Type | Description |
| ------------------ | -------------------------- | ---------------------------------------------- |
| background_color | string | Sets background color for transparent images |
| blur | number | Applies Gaussian blur (sigma value) |
| brightness | number | Adjusts brightness (-100 to 100) |
| contrast | number | Adjusts contrast (-100 to 100) |
| fill | string | Fills transparent areas (color/blur/auto/none) |
| format | ImageFormat | Sets output format |
| grayscale | boolean | Converts to grayscale |
| hue | number | Rotates the hue (0-360 degrees) |
| orient | Angle | Sets image orientation |
| proportion | number | Scales image by percentage |
| quality | number | Sets JPEG quality (0-100) |
| rgb | [number, number, number] | Adjusts RGB channels (-100 to 100 each) |
| rotate | Angle | Rotates image by fixed angles |
| saturation | number | Adjusts color saturation (-100 to 100) |
| sharpen | number | Applies sharpening effect |
| focal | string | Sets focal point for cropping |
| round_corner | object | Adds rounded corners |
| max_bytes | number | Limits output file size |
| max_frames | number | Limits animation frames |
| page | number | Selects specific page/frame |
| dpi | number | Sets DPI for vector formats |
| strip_exif | boolean | Removes EXIF metadata |
| strip_icc | boolean | Removes ICC profile |
| strip_metadata | boolean | Removes all metadata |
| upscale | boolean | Allows upscaling with fit-in |
| attachment | string | Sets download filename |
| expire | number | Sets content expiration |
| preview | boolean | Skips result storage |
| raw | boolean | Returns unprocessed image |
Build Methods
.buildRemote()
Builds and signs the final URL for the image transformation using the image service client API.
Returns
A promise that resolves to the signed URL string.
.build()
Builds and signs the final URL for the image transformation locally.
Returns
A signed URL string.
React API
Components
<Provider>
Provides configuration to its child hooks and components.
Props
| Name | Type | Required? | Description |
| --------------- | -------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| url | string \| {get: string; put: string} | Yes | The base URL where blob storage (PUT) and serve (GET) requests will be sent. Your file blob key will be joined to this URL. |
| maxUploadSize | number | No | The maximum size of an image that can be uploaded in bytes. |
Hooks
useDropzone()
A hook that creates a clickable dropzone for files. This is a convenience
wrapper around useSelectFiles and useDropFiles.
Options
| Name | Type | Required? | Description |
| ---------- | ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| accept | string | No | A comma-separated list of content types your users are allowed to select in the browser dialog, e.g. IMAGE_MIMES |
| multiple | boolean | No | Set to true if you want to allow multiple files to be selected at once. |
| key | Key | No | Set the key that will be stored in blob storage for the file. Defaults to the file name. |
| onSelect | OnSelect | No | Called each time a file is selected. |
Returns
type ReturnType = {
/**
* Props that can directly added to a dropzone container.
*/
props: React.HTMLAttributes<HTMLElement>;
/**
* Whether or not the dropzone is actively being dragged voer.
*/
isActive: dropFiles.isActive;
};useSelectFiles()
A hook that returns a callback which opens a browser dialog for selecting files when called.
Options
| Name | Type | Required? | Description |
| ---------- | ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| accept | string | No | A comma-separated list of content types your users are allowed to select in the browser dialog, e.g. IMAGE_MIMES |
| multiple | boolean | No | Set to true if you want to allow multiple files to be selected at once. |
| onSelect | OnSelect | No | Called each time a file is selected. |
Returns
export type SelectFilesCallback = (options?: {
/**
* The key that will be stored in blob storage for the file.
*/
key?: Key;
}) => void;useDropFiles()
A hook that handles drag-n-drop file uploads.
Options
| Name | Type | Required? | Description |
| ---------- | ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| accept | string | No | A comma-separated list of content types your users are allowed to select in the browser dialog, e.g. IMAGE_MIMES |
| multiple | boolean | No | Set to true if you want to allow multiple files to be selected at once. |
| key | Key | No | Set the key that will be stored in blob storage for the file. Defaults to the file name. |
| onSelect | OnSelect | No | Called each time a file is selected. |
Returns
type ReturnType = {
/**
* Props that can directly added to a dropzone container.
*/
props: React.HTMLAttributes<HTMLElement>;
/**
* Whether or not the dropzone is actively being dragged voer.
*/
isActive: dropFiles.isActive;
};useSelectDirectory()
A hook that returns a callback that opens a browser dialog for selecting files from an entire directory when called.
Options
| Name | Type | Required? | Description |
| ---------- | ---------- | --------- | ------------------------------------ |
| onSelect | OnSelect | No | Called each time a file is selected. |
Returns
export type SelectFilesCallback = (options?: {
/**
* The key that will be stored in blob storage for the file.
*/
key?: Key;
}) => void;useSelectedFile()
A hook that returns the raw file File object from a selected file and the key.
Arguments
| Name | Type | Required? | Description |
| -------------- | -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| selectedFile | SelectedFile | No | A file that was selected with any of the useDropzone, useSelectFiles, useDropFiles, or useSelectDirectory hooks. |
Returns
type ReturnType = {
/**
* The key that will be added via the blob storage API
*/
key: file.key;
/**
* The raw `File` object created by the browser
*/
file: file.file;
};useUploadFile()
A hook that returns a callback for uploading a file to the server.
Returns
A callback used to upload a single file to blob storage.
async function uploadFile(
file: SelectedFile,
options: UploadFileOptions = {},
): Promise<void>;
type UploadFileOptions = {
/**
* The key that will be stored in the key/value store for the file.
*/
key?: Key;
/**
* Additional headers to send with the upload request
*/
headers?: Record<string, string>;
/**
* Whether or not to send cookies with the upload request
*/
withCredentials?: boolean;
/**
* A function that is called when the upload is aborted
*/
onAbort?: (selectedFileData: Pick<SelectedFileData, "key" | "file">) => void;
/**
* Called when all of the files have successfully uploaded
*/
onSuccess?: (
selectedFileData: Pick<SelectedFileData, "key" | "file">,
response: Response,
) => Promise<void> | void;
/**
* Called when there is a progress event
*/
onProgress?: (
selectedFileData: Pick<SelectedFileData, "key" | "file">,
progress: ProgressData,
) => Promise<void> | void;
/**
* Called when there was an error uploading
*/
onError?: (
selectedFileData: Pick<SelectedFileData, "key" | "file">,
err: unknown,
) => Promise<void> | void;
};useUploadFiles()
A hook that returns a function for uploading multiple files concurrently with a configurable concurrency limit.
Returns
A callback used to upload multiple files to blob storage.
async function uploadFiles(
selectedFiles: Array<SelectedFile>,
options: {
/**
* Maximum number of concurrent uploads
* @default 3
*/
concurrency?: number;
} & UploadFileOptions = {},
): Promise<void>;useProgress()
A hook that returns detailed progress information for a file upload. This includes the upload rate, estimated time remaining, and other upload statistics.
Arguments
| Name | Type | Required? | Description |
| -------------- | -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| selectedFile | SelectedFile | No | A file that was selected with any of the useDropzone, useSelectFiles, useDropFiles, or useSelectDirectory hooks. |
Returns
Progress information including:
total- Total file size in bytesloaded- Number of bytes uploadedprogress- Upload progress as a fraction between 0-1rate- Upload speed in bytes per secondestimatedTimeRemaining- Estimated milliseconds until completion, or null if not startedtimeElapsed- Milliseconds since upload started
useStatus()
A hook that returns the status from a selected file.
usePreview()
Arguments
| Name | Type | Required? | Description |
| -------------- | -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| selectedFile | SelectedFile | No | A file that was selected with any of the useDropzone, useSelectFiles, useDropFiles, or useSelectDirectory hooks. |
Returns
The file status
export type SelectedFileStatus =
| "idle"
| "queued"
| "uploading"
| "aborted"
| "success"
| "error";useAbort()
A hook that returns a callback for cancelling a file upload if possible.
Arguments
| Name | Type | Required? | Description |
| -------------- | -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| selectedFile | SelectedFile | No | A file that was selected with any of the useDropzone, useSelectFiles, useDropFiles, or useSelectDirectory hooks. |
Returns
A callback that signals the abort controller for the file and sets its status to cancelled when the
file isn't in a eterminal state (success/error).
Utility functions
hashFile()
Get the SHA-256 hash of a file's contents
Arguments
| Name | Type | Required? | Description |
| ------ | ------ | --------- | ---------------- |
| file | File | Yes | The file to hash |
Returns
A promise that resolves with the SHA-256 hash of the file's contents
async function hashFile(file: File): Promise<string>;extname()
Get the file extension of a file
Arguments
| Name | Type | Required? | Description |
| ------ | ------ | --------- | ---------------- |
| file | File | Yes | The file to hash |
Returns
The file extension
function extname(file: File): string;Constants
IMAGE_MIMES
MIME types for images. Can be used with the accept option in useSelectFiles to restrict
which files can be selected in the browser dialog.
