File upload component for Angular. Supports: image cropping, drag-and-drop, and more.
To install via NPM:
npm install @bytescale/upload-widget @bytescale/upload-widget-angular
To import the module in your Angular app:
1import { NgModule } from "@angular/core";2import { BrowserModule } from "@angular/platform-browser";3import { UploadWidgetModule } from "@bytescale/upload-widget-angular";4
5import { AppComponent } from "./app.component";6
7@NgModule({8 declarations: [AppComponent],9 imports: [10 BrowserModule,11 UploadWidgetModule // <-- Add the UploadWidgetModule here.12 ],13 bootstrap: [AppComponent]14})15export class AppModule {}
To add file uploads to your web app, use these code snippets:
1import { Component } from '@angular/core';2import { UploadWidgetConfig, UploadWidgetResult } from '@bytescale/upload-widget';3
4@Component({5 selector: 'app-root',6 template: `7 <a href="{{ uploadedFileUrl }}" target="_blank">{{ uploadedFileUrl }}</a>8 <button9 uploadButton10 [uploadOptions]="options"11 [uploadComplete]="onComplete"12 >13 Upload a file...14 </button>15 `,16})17export class AppComponent {18 options: UploadWidgetConfig = {19 apiKey: "free", // Get API key: https://www.bytescale.com/get-started20 maxFileCount: 1021 };22 onComplete = (files: UploadWidgetResult[]) => {23 this.uploadedFileUrl = files[0]?.fileUrl;24 };25 uploadedFileUrl: string | undefined = undefined;26}
1import { Component } from "@angular/core";2import { UploadWidgetConfig, UploadWidgetResult, UploadWidgetOnUpdateEvent } from "@bytescale/upload-widget";3
4@Component({5 selector: "app-root",6 template: `7 <upload-dropzone [options]="options"8 [onUpdate]="onUpdate"9 [width]="width"10 [height]="height">11 </upload-dropzone>12 `13})14export class AppComponent {15 options: UploadWidgetConfig = {16 apiKey: "free", // Get API key: https://www.bytescale.com/get-started17 maxFileCount: 1018 };19 // 'onUpdate' vs 'onComplete' attrs on 'upload-dropzone':20 // - Dropzones are non-terminal by default (they don't have an end21 // state), so by default we use 'onUpdate' instead of 'onComplete'.22 // - To create a terminal dropzone, use the 'onComplete' attribute23 // instead and add the 'showFinishButton: true' option.24 onUpdate = ({ uploadedFiles, pendingFiles, failedFiles }: UploadWidgetOnUpdateEvent) => {25 const uploadedFileUrls = uploadedFiles.map(x => x.fileUrl).join("\n");26 console.log(uploadedFileUrls);27 };28 width = "600px";29 height = "375px";30}
Special behavior for dropzones:
onComplete only fires when showFinishButton = true (i.e. when the user clicks "Finish").
onUpdate must be used when showFinishButton = false.
Default value: showFinishButton = false
The onComplete callback receives the following:
[ { "accountId": "YOUR_ACCOUNT_ID", "filePath": "/uploads/image.jpg", "fileUrl": "https://upcdn.io/A623uY2/raw/uploads/image.jpg", "originalFile": { "accountId": "YOUR_ACCOUNT_ID", "etag": "33a64df551425fcc55e4d42a148795d9f25f89d4", "filePath": "/uploads/image.jpg", "fileUrl": "https://upcdn.io/A623uY2/raw/uploads/image.jpg", "lastModified": 1615680311115, "metadata": { "myCustomField1": true, "myCustomField2": { "hello": "world" }, "anotherCustomField": 42 }, "mime": "image/jpeg", "originalFileName": "example.jpg", "size": 43182, "tags": [ "example_tag" ] } }]
See: UploadWidgetResult
The onUpdate callback receives the following:
1{2 "uploadedFiles": [],3 "failedFiles": [],4 "pendingFiles": [5 {6 "file": {7 "name": "my-file.txt",8 "type": "text/plain",9 "size": 4210 }11 }12 ]13}
The uploadedFiles field uses the same structure as the onComplete param above.
The options object has the following structure (all fields optional, except for apiKey, which is required):
{ "apiKey": "public_A623uY2RvnNq1vZ80fYgGyhKN0U7", "editor": { "images": { "allowResizeOnMove": true, "crop": true, "cropFilePath": Function, "cropRatio": 1, "cropShape": "circ", "preview": true } }, "layout": "modal", "locale": { "addAnotherFileBtn": "Add another file...", "addAnotherImageBtn": "Add another image...", "cancelBtn": "cancel", "cancelBtnClicked": "cancelled", "cancelPreviewBtn": "Cancel", "continueBtn": "Continue", "cropBtn": "Crop", "customValidationFailed": "Failed to validate file.", "doneBtn": "Done", "fileSizeLimitPrefix": "File size limit:", "finishBtn": "Finished", "finishBtnIcon": true, "imageCropNumberPrefix": "Image", "maxFilesReachedPrefix": "Maximum number of files:", "maxImagesReachedPrefix": "Maximum number of images:", "orDragDropFile": "...or drag and drop a file.", "orDragDropFileMulti": "...or drag and drop files.", "orDragDropImage": "...or drag and drop an image.", "orDragDropImageMulti": "...or drag and drop images.", "processingFile": "Processing file...", "removeBtn": "remove", "removeBtnClicked": "removed", "submitBtnError": "Error!", "submitBtnLoading": "Please wait...", "unsupportedFileType": "File type not supported.", "uploadFileBtn": "Upload a File", "uploadFileMultiBtn": "Upload Files", "uploadImageBtn": "Upload an Image", "uploadImageMultiBtn": "Upload Images", "xOfY": "of" }, "maxFileCount": 1, "maxFileSizeBytes": 10485760, "metadata": { "myCustomField1": true, "myCustomField2": { "hello": "world" }, "anotherCustomField": 42 }, "mimeTypes": [ "image/jpeg" ], "multi": false, "onInit": Function, "onPreUpload": Function, "onUpdate": Function, "path": { "fileName": "image.jpg", "fileNameFallback": "image.jpg", "fileNameVariablesEnabled": true, "folderPath": "/uploads", "folderPathVariablesEnabled": true }, "showFinishButton": true, "showRemoveButton": true, "styles": { "breakpoints": { "fullScreenHeight": 420, "fullScreenWidth": 750 }, "colors": { "active": "#528fff", "error": "#d23f4d", "primary": "#377dff", "shade100": "#333", "shade200": "#7a7a7a", "shade300": "#999", "shade400": "#a5a6a8", "shade500": "#d3d3d3", "shade600": "#dddddd", "shade700": "#f0f0f0", "shade800": "#f8f8f8", "shade900": "#fff" }, "fontFamilies": { "base": "-apple-system, blinkmacsystemfont, Segoe UI, helvetica, arial, sans-serif" }, "fontSizes": { "base": 16 } }, "tags": [ "example_tag" ]}
See: UploadWidgetConfig
You can disable image, video, and PDF previews by setting preview: false
You can disable the image cropper by setting crop: false
You can transform uploaded files using Bytescale's File Processing APIs:
After uploading a file, you should save its filePath to your DB instead of its fileUrl, and use the UrlBuilder to lazily create URLs:
filePath values are shorter.
filePath values allow you to change the domain in the future (e.g. if you move to a custom CNAME).
filePath values allow you to select different file transformations at runtime (e.g. /raw/, /image/, etc.).
Install the Bytescale JavaScript SDK to use the UrlBuilder:
npm install @bytescale/sdk
Using the UrlBuilder to get raw file URLs (i.e. URLs to original files):
// import * as Bytescale from "@bytescale/sdk";
// Returns: "https://upcdn.io/1234abc/raw/example.jpg"Bytescale.UrlBuilder.url({ accountId: "1234abc", filePath: "/example.jpg"});
You can upload any file type to Bytescale. Use /raw/ when downloading files that don't need to be transformed.
Using the UrlBuilder to transform files using transformation presets:
// import * as Bytescale from "@bytescale/sdk";
// Returns: "https://upcdn.io/1234abc/thumbnail/example.jpg"Bytescale.UrlBuilder.url({ accountId: "1234abc", filePath: "/example.jpg", options: { transformation: "preset", transformationPreset: "thumbnail" }});
Transformation presets are created in the Bytescale Dashboard.
Using the UrlBuilder to transform images using the Image Processing API:
// import * as Bytescale from "@bytescale/sdk";
// Process images with:// ↪ https://upcdn.io/abc1234/image/example.jpg?w=800&h=600Bytescale.UrlBuilder.url({ accountId: "abc1234", filePath: "/example.jpg", options: { transformation: "image", transformationParams: { "w": 800, "h": 600 } }});
See the Image Processing API for the full list of transformationParams when transformation: "image".
Using the UrlBuilder to transform videos using the Video Processing API:
// import * as Bytescale from "@bytescale/sdk";
// Process videos with:// ↪ https://upcdn.io/abc1234/video/example.mov?f=mp4-h264&h=1080Bytescale.UrlBuilder.url({ accountId: "abc1234", filePath: "/example.mov", options: { transformation: "video", transformationParams: { "f": "mp4-h264", "h": 1080 } }});
See the Video Processing API for the full list of transformationParams when transformation: "video".
Using the UrlBuilder to transform audio using the Audio Processing API:
// import * as Bytescale from "@bytescale/sdk";
// Process audio with:// ↪ https://upcdn.io/abc1234/audio/example.wav?f=aac&br=192Bytescale.UrlBuilder.url({ accountId: "abc1234", filePath: "/example.wav", options: { transformation: "audio", transformationParams: { "f": "aac", "br": 192 } }});
See the Audio Processing API for the full list of transformationParams when transformation: "audio".
Using the UrlBuilder to extract the file document.docx from the uploaded ZIP file example.zip:
// import * as Bytescale from "@bytescale/sdk";
// Returns: "https://upcdn.io/1234abc/archive/example.zip?m=extract&artifact=/document.docx"Bytescale.UrlBuilder.url({ accountId: "1234abc", filePath: "/example.zip", options: { transformation: "archive", transformationParams: { m: "extract" }, artifact: "/document.docx" }});
See the Archive Processing API for the full list of transformationParams when transformation: "archive".
Using the UrlBuilder to scan files for viruses, trojans, and other malware:
// import * as Bytescale from "@bytescale/sdk";
// Returns: "https://upcdn.io/1234abc/antivirus/example.zip"Bytescale.UrlBuilder.url({ accountId: "1234abc", filePath: "/example.zip", options: { transformation: "antivirus" }});
See the Antivirus API for full details about the JSON response structure.
The Bytescale Upload Widget requires a Bytescale API key, and optionally a JWT:
You must always pass an apiKey to the Upload Widget configuration object.
With API key auth, the requester has access to the resources configured in the API key's permissions.
Secret API keys: can perform all API operations (see the Bytescale JavaScript SDK).
Public API keys: can perform file uploads and file downloads only. File overwrites, file deletes, and all other destructive operations cannot be performed using public API keys.
You must always use public API keys (e.g. public_***) in your client-side code.
When using public API keys you can optionally pass a JWT to extend the requester's permissions beyond that of the API key. In addition, you can configure your API key to make it reject requests that aren't accompanied by a valid JWT. This prevents users from taking your API key and using it outside of your application.
JWTs are issued by your application and are verified by Bytescale using a public key certificate.
To use JWTs, please use the Bytescale JavaScript SDK AuthManager »
This website uses cookies. By continuing you are consenting to the use of cookies per our Cookie Policy. Our legal policies were last updated August 16 2024.
This website requires a modern web browser -- the latest versions of these browsers are supported: