Page updated Jan 16, 2024

Download files

Get

Get a presigned URL of a stored file. You can specify some options: mainly file access level and whether to download the file:

1await Storage.get(key: string, config: {
2 level?: private | protected | public, // defaults to `public`
3 identityId?: string, // id of another user, if `level: protected`
4 download?: boolean, // defaults to false
5 expires?: number, // validity of the URL, in seconds. defaults to 900 (15 minutes) and maxes at 3600 (1 hour)
6 contentType?: string, // set return content type, eg "text/html"
7 validateObjectExistence?: boolean, // defaults to false
8 cacheControl?: string, // Specifies caching behavior along the request/reply chain
9});

Storage.get returns a signed URL string to your file if download is false, which is the default. You can use this to create a download link for users to click on. Note that this function does not check if the file exists by default. You can enable this check by setting validateObjectExistence to true.

Note: Currently, the expiration time of the presigned url is dependent on the session and will max out at 1 hour.

1// get the signed URL string
2const signedURL = await Storage.get(key); // get key from Storage.list
3
4// inside your template or JSX code. Note <a download> doesn't work here because it is not same origin
5<a href={signedURL} target="_blank" rel="noreferrer">
6 {fileName}
7</a>;

Check for existence of a file

You can check for the existence of a file in the storage category's get API using the validateObjectExistence option. When this flag is enabled a get call will return a pre-signed URL if the file exists and raise a 404 error if it does not. This allows you to check if an object exists during generating the presigned URL, which you can then use to download that object.

1// To check for existence of a file
2await Storage.get('filename.txt', { validateObjectExistence: true });

If download is true, Storage.get returns an object with a Body field of type Blob. It is up to you to programmatically save it to disk (we suggest a method below) or do whatever else you need with it.

File download option

The download option send you the object data for download or programmatic manipulation:

1const result = await Storage.get(`filename.txt`, { download: true });
2
3// data.Body is a Blob
4result.Body.text().then((string) => {
5 // handle the String data return String
6});

You can programmatically download Blobs using JavaScript:

1export function downloadBlob(blob, filename) {
2 const url = URL.createObjectURL(blob);
3 const a = document.createElement('a');
4 a.href = url;
5 a.download = filename || 'download';
6 const clickHandler = () => {
7 setTimeout(() => {
8 URL.revokeObjectURL(url);
9 a.removeEventListener('click', clickHandler);
10 }, 150);
11 };
12 a.addEventListener('click', clickHandler, false);
13 a.click();
14 return a;
15}
16
17// usage
18async function download() {
19 const result = await Storage.get(fileKey, { download: true });
20 downloadBlob(result.Body, 'filename');
21}

The full return signature of Storage.get(key, { download: true }) looks like this:

1{
2 $metadata: {
3 attempts: 1
4 httpHeaders: {content-length: "388187", content-type: "audio/x-m4a", last-modified: "Fri, 09 Oct 2020 14:29:13 GMT", x-amz-id-2: "/rRqsX/c2h5V00tYMtDY994wEenyPm0SDw1lyWyncWepyg+T6YJJSjLHKIsz0dxMI3kN5KjA6GQ=", …}
5 httpStatusCode: 200
6 requestId: undefined
7 totalRetryDelay: 0
8 },
9 Body: Blob {size: 388187, type: "audio/x-m4a"}, // this will vary
10 ContentLength: 388187,
11 ContentType: "audio/x-m4a",
12 ETag: ""c05e324f61613c2472d47a8ee6fbb628"",
13 LastModified: Fri Oct 09 2020 22:29:13 GMT+0800 (Singapore Standard Time) {},
14 Metadata: {},
15 __type: "GetObjectOutput",
16}

Monitor progress of download

To track the progress of your download, you can use progressCallback:

1Storage.get('filename.txt', {
2 download: true,
3 progressCallback(progress) {
4 console.log(`Downloaded: ${progress.loaded}/${progress.total}`);
5 }
6});

File Access Levels

You can choose to configure access level ahead of time, or at the point of calling Storage.get:

1// Option 1: configure access ahead of time
2Storage.configure({ level: 'private' });
3const result = await Storage.get('welcome.png'); // Gets the welcome.png belonging to current user
4
5// Option 2: configure access inside the call
6const result = await Storage.get('welcome.png', { level: 'private' }); // same effect

Here is a quick guide to the access levels - see the docs for more detail:

  • public: Accessible by all users of your app. Files are stored under the public/ path in your S3 bucket.
  • protected: Readable by all users, but writable only by the creating user. Files are stored under protected/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.
1// To get current user's objects
2const result = await Storage.get('filename.txt', { level: 'protected' });
3
4// To get other users' objects
5const result = await Storage.get('filename.txt', {
6 level: 'protected',
7 identityId: 'xxxxxxx' // the identityId of that user
8});
  • private: Only accessible for the signed in user. Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.

Download expiry

You can use expires option to limit the availability of your URLs. This configuration returns the pre-signed URL that expires in 60 seconds:

1await Storage.get('filename.txt', { expires: 60 });

Frequently Asked Questions

Users can run into unexpected issues, so we are giving you advance notice in documentation with links to open issues - please vote for what you need, to help the team prioritize.