## Upload File
To upload to S3 from a file, specify the `key` and the `localFile` to be uploaded, where the `localFile` can be an instance of `AWSFile` created from either an OS platform `File` instance or the result of Flutter file picker plugins such as [file_picker](https://pub.dev/packages/file_picker).
### Upload platform `File`
**Note**: To use `AWSFilePlatform`, add [aws_common](https://pub.dev/packages/aws_common) package to your Flutter project
by running: `flutter pub add aws_common`
```dart
import 'dart:io' as io;
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
import 'package:aws_common/vm.dart';
Future uploadIOFile(io.File file) async {
final awsFile = AWSFilePlatform.fromFile(file);
try {
final uploadResult = await Amplify.Storage.uploadFile(
localFile: awsFile,
key: 'upload/file.png',
).result;
safePrint('Uploaded file: ${uploadResult.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading file: ${e.message}');
rethrow;
}
}
```
```dart
import 'dart:html' as html;
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
import 'package:aws_common/web.dart';
Future uploadHtmlFile(html.File file) async {
final awsFile = AWSFilePlatform.fromFile(file);
try {
final uploadResult = await Amplify.Storage.uploadFile(
localFile: awsFile,
key: 'upload/file.png',
).result;
safePrint('Uploaded file: ${uploadResult.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading file: ${e.message}');
rethrow;
}
}
```
### Upload with Flutter file_picker plugin
The [file_picker](https://pub.dev/packages/file_picker) plugin can be used to retrieve arbitrary file types from the user's device.
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:file_picker/file_picker.dart';
Future uploadImage() async {
// Select a file from the device
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
withData: false,
// Ensure to get file stream for better performance
withReadStream: true,
allowedExtensions: ['jpg', 'png', 'gif'],
);
if (result == null) {
safePrint('No file selected');
return;
}
// Upload file with its filename as the key
final platformFile = result.files.single;
try {
final result = await Amplify.Storage.uploadFile(
localFile: AWSFile.fromStream(
platformFile.readStream!,
size: platformFile.size,
),
key: platformFile.name,
onProgress: (progress) {
safePrint('Fraction completed: ${progress.fractionCompleted}');
},
).result;
safePrint('Successfully uploaded file: ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading file: $e');
rethrow;
}
}
```
## Upload Data
To upload to S3 from a data object, specify the `key` and `data`, where `data` is an instance of `S3DataPayload` created from various data formats.
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
Future uploadStringData({
required String dataString,
required String key,
}) async {
try {
final result = await Amplify.Storage.uploadData(
data: S3DataPayload.string(
dataString,
contentType: 'text/plain',
),
key: key,
).result;
safePrint('Uploaded data: ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading data: ${e.message}');
rethrow;
}
}
```
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
Future uploadJsonObject({
required Map json,
required String key,
}) async {
try {
final result = await Amplify.Storage.uploadData(
data: S3DataPayload.json(json),
key: key,
).result;
safePrint('Uploaded data: ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading data: ${e.message}');
rethrow;
}
}
```
`S3DataPayload.dataUrl()` parses the provided data URL string, and throws exception if the data URL is invalid. See more info about [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs).
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
Future uploadDataUrl({
required String dataUrl,
required String key,
}) async {
try {
final result = await Amplify.Storage.uploadData(
data: S3DataPayload.dataUrl(dataUrl),
key: key,
).result;
safePrint('Uploaded data: ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading data: ${e.message}');
rethrow;
}
}
```
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
Future uploadBytes({
required List bytes,
required String key,
required String contentType,
}) async {
try {
final result = await Amplify.Storage.uploadData(
data: S3DataPayload.bytes(
bytes,
contentType: contentType,
),
key: key,
).result;
safePrint('Uploaded data: ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading data: ${e.message}');
rethrow;
}
}
```
## Upload Options
You can attach metadata while uploading data or a file by specifying the `metadata` property in options. If you want the `metadata` to be included in the upload result, you can set the `getProperties` flag to `true` in options.
```dart
Future uploadWithOptions() async {
// When uploading data, use `StorageUploadDataOptions`
final uploadDataOperation = Amplify.Storage.uploadData(
data: S3DataPayload.string(
'example',
contentType: 'text/plain',
),
key: 'example.txt',
options: const StorageUploadDataOptions(
metadata: {
'project': 'ExampleProject',
},
pluginOptions: S3UploadDataPluginOptions(
getProperties: true,
),
),
);
final uploadDataResult = await uploadDataOperation.result;
safePrint(
'Uploaded data with metadata: ${uploadDataResult.uploadedItem.metadata}',
);
// When uploading a file, use `StorageUploadFileOptions`
final uploadFileOperation = Amplify.Storage.uploadFile(
localFile: AWSFile.fromPath('path/to/example.txt'),
key: 'example.txt',
options: const StorageUploadFileOptions(
metadata: {
'project': 'ExampleProject',
},
pluginOptions: S3UploadFilePluginOptions(
getProperties: true,
),
),
);
final uploadFileResult = await uploadFileOperation.result;
safePrint(
'Uploaded file with metadata: ${uploadFileResult.uploadedItem.metadata}',
);
}
```
The [`Amplify.Storage.getProperties` API](/lib/storage/get-properties) allows you to retrieve metadata without downloading the file.
In S3 console, you should see the metadata attached to your file as the following.

## Control of Upload Operations
A call to `Amplify.Storage.uploadFile` or `Amplify.Storage.uploadData` returns a reference to the operation that is performing the upload.
To cancel the upload (for example, in response to the user pressing a Cancel button), simply call `.cancel()` on the returned upload operation.
```dart
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
S3UploadFileOperation? uploadOperation;
Future uploadFile(String path) async {
try {
final storagePlugin = Amplify.Storage.getPlugin(AmplifyStorageS3.pluginKey);
uploadOperation = storagePlugin.uploadFile(
localFile: AWSFile.fromPath(path),
key: 'example_file.txt',
);
final result = await uploadOperation!.result;
safePrint('Uploaded ${result.uploadedItem.key}');
} on StorageException catch (e) {
safePrint('Error uploading file: ${e.message}');
}
}
void cancelUpload() {
uploadOperation?.cancel();
uploadOperation = null;
}
```
## Multipart Upload
Amplify will automatically perform a S3 multipart upload for files larger than 5MB. For more information about S3's multipart upload support, see [Uploading and copying objects using multipart upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html).