On this page

This guide assumes that you have followed the steps in the
[Getting Started](/content/docs/get-started/index.html) guide, and have the access keys
available.

You may continue to use the AWS JS SDK as you normally would, but with the
endpoint set to Tigris at [https://t3.storage.dev](https://t3.storage.dev/). Also
make sure that `s3ForcePathStyle` is set to `false`.

```js
import { S3Client } from "@aws-sdk/client-s3";

const S3 = new S3Client({

region: "auto",

endpoint: "https://t3.storage.dev",

s3ForcePathStyle: false,

});
```

## Getting started

This example uses the
[AWS Node.js SDK v3](https://www.npmjs.com/package/@aws-sdk/client-s3) and reads
the default credentials file or the environment variables `AWS_ACCESS_KEY_ID`
and `AWS_SECRET_ACCESS_KEY`.

```js
import {

S3Client,

paginateListBuckets,

paginateListObjectsV2,

PutObjectCommand,

} from "@aws-sdk/client-s3";

import { readFile } from "node:fs/promises";

// listBuckets returns a list of all S3 buckets in the account with
// metadata such as creation date and owner.

export const listBuckets = async (S3) => {

const buckets = [];

for await (const page of paginateListBuckets({ client: S3 }, {})) {

if (page.Buckets) {

buckets.push(...page.Buckets);

}

}

return buckets;
};

// listObjects returns a list of all objects in a bucket. This only returns
// the keys of the objects, not the objects themselves. Customize the
// objects.push line to return more metadata about the objects.

export const listObjects = async (S3, bucketName) => {

const paginator = paginateListObjectsV2(

{ client: S3, pageSize: 100 },

{ Bucket: bucketName },

);

const objects = [];

for await (const page of paginator) {

if (page.Contents) {

objects.push(page.Contents.map((o) => o.Key)); // only get object keys

}

}

return objects;
};

// uploadObjectFromFS uploads a file from the local filesystem to an S3 bucket.
// This does not handle large files or multipart uploads.

export const uploadObjectFromFS = async (S3, bucket, key, filePath) => {

const command = new PutObjectCommand({

Bucket: bucket,

Key: key,

Body: await readFile(filePath),

});

const response = await S3.send(command);

return response;
};

const S3 = new S3Client({

region: "auto",

s3ForcePathStyle: false,

});

console.log("List buckets");

const buckets = await listBuckets(S3);

console.log("Buckets:", buckets);

console.log("List objects in a bucket");

const objects = await listObjects(S3, "tigris-example");
objects.forEach((objects, pageNum) => {

console.log(`Page ${pageNum + 1}:`, objects);

});

console.log("Upload an object");

const response = await uploadObjectFromFS(

S3,

"tigris-example",

"examples/js/getting-started.js",

"getting-started.js",

);

console.log("Upload response:", response);
```

## Using presigned URLs

Presigned URLs can be used with the AWS Node.js SDK as follows:

```js
import {

S3Client,

GetObjectCommand,

PutObjectCommand,

DeleteObjectCommand,

} from "@aws-sdk/client-s3";

import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const S3 = new S3Client({

region: "auto",

s3ForcePathStyle: false,

});

// Presigned GET, allows users to download objects without making the bucket public.
console.log(

"GET:",

await getSignedUrl(

S3,

new GetObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),

{ expiresIn: 3600 }, // 1 hour

),

);

// Presigned PUT, allows users to upload objects without going through your server.
console.log(

"PUT:",

await getSignedUrl(

S3,

new PutObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),

{ expiresIn: 3600 }, // 1 hour

),

);

// Presigned DELETE, allows users to delete objects.
console.log(

"DELETE:",

await getSignedUrl(

S3,

new DeleteObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),

{ expiresIn: 3600 }, // 1 hour

),

);
```

You can now use the URL returned by the `getSignedUrl` function to download or
upload objects to the bucket using the `https` package.

### Presigned URLs with custom domains

You can also use a
[presigned URL with a custom domain](/content/docs/objects/presigned/#presigned-url-with-custom-domain/index.html)
by replacing the bucket host with your custom domain:

```js
const brandedURL = presignedUrl.replace(

"foo-bucket.t3.storage.dev",

"your-domain.example.com",

);

console.log("Presigned URL for GET (custom domain):", brandedURL);
```

## Renaming objects

[Objects can be renamed](/content/docs/objects/object-rename/index.html) in Tigris by attaching
the `X-Tigris-Rename` header to a CopyObject request.

```js
import {

S3Client,

PutObjectCommand,

CopyObjectCommand,

DeleteObjectCommand,

HeadObjectCommand,

} from "@aws-sdk/client-s3";

import { randomUUID } from "node:crypto";

export const renameObject = async (S3, bucket, oldKey, newKey) => {

S3.middlewareStack.add(

(next) => async (args) => {

args.request.headers["X-Tigris-Rename"] = "true";

return next(args);

},

{

step: "build",

name: "renameObject",

tags: ["METADATA", "RENAME"],

},

);

const copyCommand = new CopyObjectCommand({

Bucket: bucket,

CopySource: `${bucket}/${oldKey}`,

Key: newKey,

});

await S3.send(copyCommand);

S3.middlewareStack.remove("renameObject");
};

const S3 = new S3Client({

region: "auto",

s3ForcePathStyle: false,

endpoint: "https://t3.storage.dev",
});

const bucket = "tigris-example";

const object = randomUUID();

const newObject = randomUUID();

let command = new PutObjectCommand({

Bucket: bucket,

Key: object,

Body: "Hello, Tigris!",
});

await S3.send(command);

console.log("Rename object");
await renameObject(S3, bucket, object, newObject);

command = new HeadObjectCommand({

Bucket: bucket,

Key: newObject,
});

await S3.send(command);

command = new DeleteObjectCommand({

Bucket: bucket,

Key: newObject,
});

await S3.send(command);
```
