> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Named transformations


A **named transformation** is a pre-defined set of transformation parameters that has been given a custom name for easy reference. Instead of applying each of the required transformations separately to an asset, you can apply a single named transformation to apply all the transformations defined for it. This makes it easy to: 

* Reuse transformations on multiple assets
* Shorten complex transformation URLs
* Hide the details of a transformation in your delivery URL. 
* Simplify the enabling/disabling of transformations in [Strict Transformations](control_access_to_media#strict_transformations) mode. 

Named transformations can include other named transformations, which allows you to define a chain of transformations to run on multiple assets more easily. 

They're required for [baseline transformations](transformation_reference#bl_baseline), which save processing time and cost by avoiding regeneration of shared transformation steps.

You can create and manage named transformations via the API or in the console UI using the [Transformation Builder](#transformation_builder).

Once defined, you can apply a named transformation by setting the `transformation` parameter (or `t` in a URL) to the transformation's name. For example `t_instagram-auto-crop`. 

You can include **user-defined variables** in your named transformations, and then pass the value for the user-defined variable into the transformation from an external source. This enables creating a named transformation 'template' with a lot of flexibility. 

For example, you could define a complex named transformation that includes a text overlay as a named transformation, using a user-defined variable for the text string value. 

Cloudinary automatically tracks which named transformations were used to generate each derived asset. You can view this information in the Derived Assets tab of the Manage page. For more information, see [Derived Assets](media_library_for_developers) in the Media Library for developers guide.

You can also set named transformations as [transformation templates](dam_admin_asset_management#transformation_templates), which you can apply as templates in the Media Library so that you can preview how assets will look with different named transformations applied.

For more details, see [user-defined variables](user_defined_variables). For a use-case example demonstrating named transformations with user-defined variables, see [Named transformation with a user-defined variable](user_defined_variables#named_transformation).


> **NOTES**:
>
> * Keep in mind that not all transformations support all asset types and formats. Applying a named transformation to an asset of an unsupported type or format {valeExclude}will{/valeExclude} fail and return a 404 error. You can check whether you can use the parameters in your named transformation for both images and videos in the [transformation reference](transformation_reference).  You can also check the [supported formats for transformations](formats_supported_for_transformation).

> * Before you **update** the transformation parameters of an existing named transformation that's already used in production, make sure you're aware of all existing instances. To mitigate risk, when you update the parameters of an existing named transformation (via the Console UI or API), existing derived assets using the named transformation {valeExclude}are **not**{/valeExclude} automatically invalidated and regenerated.  If you're sure you want to apply the new definition to any already derived assets with that named transformation, you must specifically [invalidate](invalidate_cached_media_assets_on_the_cdn) those transformations or otherwise modify the other parameters in that delivery URL, so that the asset {valeExclude}will be{/valeExclude} re-derived using the new definition on next request.**Tip**: You can use the [regen_derived](cloudinary_cli#regen_derived) CLI command to invalidate and then regenerate derived assets after updating the definition for a named transformation.

> * Before you **delete** an existing named transformation, make sure you aren't using that transformation in production. When you **delete** an existing named transformation via the Console UI or API, and if there are fewer than 1000 existing derived assets using that named transformation, they're automatically invalidated (and {valeExclude}will{/valeExclude} return a `404` error on the next request).  If there are 1000 or more such derived assets, the delete request fails with a `403` error indicating that your named transformation has `too many derived resources` or `too many dependent transformations` (when the derived assets use the named transformation in combination with other parameters).

## Creating named transformations
You can create a named transformation programmatically or using the Transformations UI in your Cloudinary console.

**To create a named transformation programmatically:**

Use the `Transformations` Admin API method. 

For example, the following defines a named transformation called `small_profile_thumbnail` that uses automatic cropping to resize assets to the required size for a particular application's thumbnail display: 

```multi

|ruby
Cloudinary::Api.create_transformation('small_profile_thumbnail',
  {width: 100, height: 150, crop: "fill", gravity: "auto"})

|php_2
$api->createTransformation("small_profile_thumbnail",
  ["width" => 100, "height" => 150, "crop" => "fill", "gravity" =>"auto"]);

|python
cloudinary.api.create_transformation("small_profile_thumbnail",
  dict(width = 100, height = 150, crop = "fill", gravity = "auto"))

|nodejs
cloudinary.v2.api
.create_transformation('small_profile_thumbnail',
  { width: 100, height: 150, crop: 'fill', gravity: 'auto' })
.then(result=>console.log(result));

|java
api.createTransformation("small_profile_thumbnail",
  new Transformation().width(150).height(100).crop("fill").gravity("auto").generate(),
  ObjectUtils.emptyMap());

|csharp
var createTransformParams = new CreateTransformParams(){
  Name = "small_profile_thumbnail",
  Transformation = new Transformation().Width(100).Height(150).Crop("fill").Gravity("auto")};
cloudinary.CreateTransform(createTransformParams);

|go
resp, err := cld.Admin.CreateTransformation(ctx, admin.CreateTransformationParams{
		Name:         "small_profile_thumbnail",
		Transformation: "c_fill,g_auto,h_150,w_100"})

|curl
curl \
  -d 'transformation=w_100,h_150,c_fill,g_auto' \
  -X POST \
  https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/transformations/small_profile_thumbnail

|cli
cld admin create_transformation "small_profile_thumbnail" '{"width": 150, "height": 100, "crop": "fill", "gravity": "auto"}'
```

For more details and examples, see the [Create Transformation](admin_api#create_a_named_transformation) method in the _Admin API Reference_.

**To create a named transformation using the UI:**

1. Expand the **Transform and Customize** section, accessible from the Console **Product Navigation** menu.
2. Choose one of the following options to create your named transformation:
    * **Start with a pre-defined transformation:** Select a transformation from the [Image Home](https://console.cloudinary.com/app/image/home) examples as a template and experiment with it in the UI. Click **Use it** to open the Transformation Builder and refine the transformation to your needs, and save it with your chosen name.
       
    * **Save a delivered dynamic transformation:** View all your delivered dynamic transformations (those that were generated and delivered on the fly) in the [Log](https://console.cloudinary.com/app/image/manage/log) tab of the **Manage Transformations** page and save one of those with your chosen name.
    * **Create from scratch:** Create a new transformation from scratch using the [Transformation Builder (Beta)](#transformation_builder) and save with your chosen name. Open the builder by clicking **New Transformation** from either of the Transform and Customize pages.

> **NOTE**:
>
> Names used for named transformations:

> * Must contain valid UTF8 characters only

> * Must not contain more than 1024 characters

> * Must not contain any of these characters: `\`, `/`, `?`, `&`, `#`, `%`, `.`, `,`, ``

Once you've saved your named transformations, you can view a list of them in the Console in the **[Image > Manage Transformations > Named Transformations](https://console.cloudinary.com/app/transformations/manage/named)** tab. From here, you can edit, copy, or enable/disable [Strict Transformations](control_access_to_media#strict_transformations).

You can also select to include a transformation as a [preset](dam_admin_asset_management#transformation_templates) so that users can apply it to assets using the [Download Options tab](dam_manage_individual_assets#drill_down_tabs) of the asset management drill-down page (available for **Assets Enterprise** plans).

## Transformation Builder
The Cloudinary Transformation Builder is the UI for creating and saving your transformations in a simple and easy to use way. The Transformation Builder has two modes of operation:

* [Construct](#construct_mode): Build transformations manually by selecting and configuring transformation actions.
* [Converse](#converse_mode): Build transformations using AI chat by describing the transformation with natural language.

> **INFO**: Converse mode is currently in Beta and may not yet be enabled for your account. Some implementation details may change before the official release. We invite you to request access and share any feedback via our [support team](https://support.cloudinary.com/hc/en-us/requests/new).


### Transformation Builder video tutorial

Watch this video for a quick introduction to the Transformation Builder:

  This video is brought to you by Cloudinary's video player - embed your own!Use the controls to set the playback speed, navigate to chapters of interest and select subtitles in your preferred language.
{videoTranscript:publicId=training/transformation-builder-onboarding}

### Tutorial contents This tutorial presents the following topics. Click a timestamp to jump to that part of the video.
#### Welcome to the Transformation Builder
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media2 :min=0 :sec=00 :player=cld} | Welcome to the Transformation Builder.  Here, you can play with your videos and images, either by making alterations one step at a time, or by telling our AI chat interface how you want them to look. Your original assets will remain intact, you’re just creating new variations. |

#### Edit, use and save a transformation 
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media2 :min=0 :sec=30 :player=cld} | Use the Quick Edit to tweak the result, known as a "transformation", and once you’re happy, try out the same transformation on different assets, copy the delivery URL or your preferred code snippet, or save the transformation as a "named transformation" for easier reuse in the future. |

#### Create a transformation using the Builder

**To create a new transformation:**

1. [Open the Builder](https://console.cloudinary.com/app/image/transformation_builder).
2. Select the mode to use.

![Construct and Converse selector](https://cloudinary-res.cloudinary.com/image/upload/f_auto/q_auto/docs/converse-construct.png "popup: true, thumb: w_250,dpr_2, width:250, conditional: false")

#### Construct mode

The Transformation Builder in **construct** mode provides:

* A simple and intuitive UI for selecting and configuring transformation actions - easily discover actions and parameters as you build.
* Transformations built as a series of self-contained actions so you can see the results of each one as you apply it.
* URL and SDK code ready to copy and paste directly to your code.
* The ability to update the default preview image to something from your own product environment.
* Quick edit functionality, to easily add transformations using [URL syntax](#transformation_reference).

![Transformation Builder in construct mode](https://cloudinary-res.cloudinary.com/image/upload/f_auto/q_auto/v1688632062/docs/construct-mode.png "popup: true, thumb: w_600,dpr_2, width:600, conditional: false")

The builder supports most common transformation actions. If the transformation action you are trying to apply is not listed, you can add an **Additional Transformation** action and use [transformation URL syntax](#transformation_reference) to specify your transformation. Alternatively, you can switch to the legacy editor to create your transformation.

#### Converse mode

The Transformation Builder in **converse** mode provides:

* An AI-powered conversational interface to describe the transformation you want to create with natural language. 
* Iterative prompts to continue the conversation and perfect the transformation.
* URL and SDK code ready to copy and paste directly to your code.
* The ability to update the default preview image to something from your own product environment.

![Transformation Builder in converse mode](https://cloudinary-res.cloudinary.com/image/upload/f_auto/q_auto/v1688632079/docs/converse-mode.png "popup: true, thumb: w_600,dpr_2, width:600, conditional: false")

> **NOTE**:
>
> :title=Notes and limitations:

> * The conversational interface is powered by GPT.

> * It answers questions related to Cloudinary transformations only.

> * The use of AI, including the GPT model, means that answers may not be 100% accurate.

> * We have implemented mechanisms to improve the accuracy of results for transaction-related queries compared to using ChatGPT directly.

> * We are continually learning and making improvements as this technology progresses.

## Named transformation examples

Below are two quite different named transformations applied to the same `lighthouse_reflection` image:

* **fill_square_400** is defined as `ar_1:1,c_fill,g_auto,w_400`, which fills (scales and crops) the image into a 400*400 square, automatically focussing on the most interesting area of the image:
  ![apply a 'fill_square_400' named transformation to an image](https://res.cloudinary.com/demo/image/upload/t_fill_square_400/lighthouse_reflection.jpg "thumb:w_250,dpr_2, width:250")

```nodejs
cloudinary.image("lighthouse_reflection.jpg", {transformation: ["fill_square_400"]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("fill_square_400")
);
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("fill_square_400")
);
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("fill_square_400")
);
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("fill_square_400")
);
```

```python
CloudinaryImage("lighthouse_reflection.jpg").image(transformation=["fill_square_400"])
```

```php
use Cloudinary\Transformation\NamedTransformation;

(new ImageTag('lighthouse_reflection.jpg'))
	->namedTransformation(NamedTransformation::name("fill_square_400"));
```

```java
cloudinary.url().transformation(new Transformation().named("fill_square_400")).imageTag("lighthouse_reflection.jpg");
```

```ruby
cl_image_tag("lighthouse_reflection.jpg", transformation: ["fill_square_400"])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("fill_square_400")).BuildImageTag("lighthouse_reflection.jpg")
```

```dart
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_square_400")));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("fill_square_400")).generate("lighthouse_reflection.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().named("fill_square_400")).generate("lighthouse_reflection.jpg");
```

```flutter
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_square_400")));
```

```kotlin
cloudinary.image {
	publicId("lighthouse_reflection.jpg")
	 namedTransformation(NamedTransformation.name("fill_square_400")) 
}.generate()
```

```jquery
$.cloudinary.image("lighthouse_reflection.jpg", {transformation: ["fill_square_400"]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("fill_square_400")
);
``` &nbsp;
* **rounded_cartoonified_frame** is defined as `e_cartoonify/r_max/co_rgb:add8e6,e_outline:30/b_rgb:add8e6`, which applies a cartoonify effect, rounds it to a circle or oval shape, adds a light blue outline around the oval so that the image won't be touching the edges of the frame, and then fills the transparent background with the same color as the outline:
![apply a 'rounded_cartoonified_frame' named transformation to an image](https://res.cloudinary.com/demo/image/upload/t_oval_cartoonified_frame/lighthouse_reflection.jpg "thumb:w_300")

```nodejs
cloudinary.image("lighthouse_reflection.jpg", {transformation: ["oval_cartoonified_frame"]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("oval_cartoonified_frame")
);
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("oval_cartoonified_frame")
);
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("oval_cartoonified_frame")
);
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("oval_cartoonified_frame")
);
```

```python
CloudinaryImage("lighthouse_reflection.jpg").image(transformation=["oval_cartoonified_frame"])
```

```php
use Cloudinary\Transformation\NamedTransformation;

(new ImageTag('lighthouse_reflection.jpg'))
	->namedTransformation(NamedTransformation::name("oval_cartoonified_frame"));
```

```java
cloudinary.url().transformation(new Transformation().named("oval_cartoonified_frame")).imageTag("lighthouse_reflection.jpg");
```

```ruby
cl_image_tag("lighthouse_reflection.jpg", transformation: ["oval_cartoonified_frame"])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("oval_cartoonified_frame")).BuildImageTag("lighthouse_reflection.jpg")
```

```dart
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("oval_cartoonified_frame")));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("oval_cartoonified_frame")).generate("lighthouse_reflection.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().named("oval_cartoonified_frame")).generate("lighthouse_reflection.jpg");
```

```flutter
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("oval_cartoonified_frame")));
```

```kotlin
cloudinary.image {
	publicId("lighthouse_reflection.jpg")
	 namedTransformation(NamedTransformation.name("oval_cartoonified_frame")) 
}.generate()
```

```jquery
$.cloudinary.image("lighthouse_reflection.jpg", {transformation: ["oval_cartoonified_frame"]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg").namedTransformation(
  name("oval_cartoonified_frame")
);
```

## Chaining named transformations

You can chain named transformations before or after other transformations. For example, here the `oval_cartoonified_frame` named transformation is applied after a grayscale effect:

![apply both a named and direct transformation to the image](https://res.cloudinary.com/demo/image/upload/e_grayscale/t_oval_cartoonified_frame/lighthouse_reflection.jpg "thumb:w_300")

```nodejs
cloudinary.image("lighthouse_reflection.jpg", {transformation: [
  {effect: "grayscale"},
  {transformation: ["oval_cartoonified_frame"]}
  ]})
```

```react
import { grayscale } from "@cloudinary/url-gen/actions/effect";
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .effect(grayscale())
  .namedTransformation(name("oval_cartoonified_frame"));
```

```vue
import { grayscale } from "@cloudinary/url-gen/actions/effect";
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .effect(grayscale())
  .namedTransformation(name("oval_cartoonified_frame"));
```

```angular
import { grayscale } from "@cloudinary/url-gen/actions/effect";
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .effect(grayscale())
  .namedTransformation(name("oval_cartoonified_frame"));
```

```js
import { grayscale } from "@cloudinary/url-gen/actions/effect";
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .effect(grayscale())
  .namedTransformation(name("oval_cartoonified_frame"));
```

```python
CloudinaryImage("lighthouse_reflection.jpg").image(transformation=[
  {'effect': "grayscale"},
  {'transformation': ["oval_cartoonified_frame"]}
  ])
```

```php
use Cloudinary\Transformation\Effect;
use Cloudinary\Transformation\NamedTransformation;

(new ImageTag('lighthouse_reflection.jpg'))
	->effect(Effect::grayscale())
	->namedTransformation(NamedTransformation::name("oval_cartoonified_frame"));
```

```java
cloudinary.url().transformation(new Transformation()
  .effect("grayscale").chain()
  .named("oval_cartoonified_frame")).imageTag("lighthouse_reflection.jpg");
```

```ruby
cl_image_tag("lighthouse_reflection.jpg", transformation: [
  {effect: "grayscale"},
  {transformation: ["oval_cartoonified_frame"]}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("grayscale").Chain()
  .Named("oval_cartoonified_frame")).BuildImageTag("lighthouse_reflection.jpg")
```

```dart
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.effect(Effect.grayscale())
	.namedTransformation(NamedTransformation.name("oval_cartoonified_frame")));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setEffect("grayscale").chain()
  .setNamed("oval_cartoonified_frame")).generate("lighthouse_reflection.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .effect("grayscale").chain()
  .named("oval_cartoonified_frame")).generate("lighthouse_reflection.jpg");
```

```flutter
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.effect(Effect.grayscale())
	.namedTransformation(NamedTransformation.name("oval_cartoonified_frame")));
```

```kotlin
cloudinary.image {
	publicId("lighthouse_reflection.jpg")
	 effect(Effect.grayscale())
	 namedTransformation(NamedTransformation.name("oval_cartoonified_frame")) 
}.generate()
```

```jquery
$.cloudinary.image("lighthouse_reflection.jpg", {transformation: [
  {effect: "grayscale"},
  {transformation: ["oval_cartoonified_frame"]}
  ]})
```

```react_native
import { grayscale } from "@cloudinary/url-gen/actions/effect";
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .effect(grayscale())
  .namedTransformation(name("oval_cartoonified_frame"));
```

You can also chain multiple named transformations. For example, to chain the named transformations defined in the previous section{variable:videoDuNote}:

![Applying multiple named transformations](https://res.cloudinary.com/demo/image/upload/t_fill_square_400/t_rounded_cartoonified_frame/lighthouse_reflection.jpg "thumb:w_250")

```nodejs
cloudinary.image("lighthouse_reflection.jpg", {transformation: [
  {transformation: ["fill_square_400"]},
  {transformation: ["rounded_cartoonified_frame"]}
  ]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .namedTransformation(name("fill_square_400"))
  .namedTransformation(name("rounded_cartoonified_frame"));
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .namedTransformation(name("fill_square_400"))
  .namedTransformation(name("rounded_cartoonified_frame"));
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .namedTransformation(name("fill_square_400"))
  .namedTransformation(name("rounded_cartoonified_frame"));
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .namedTransformation(name("fill_square_400"))
  .namedTransformation(name("rounded_cartoonified_frame"));
```

```python
CloudinaryImage("lighthouse_reflection.jpg").image(transformation=[
  {'transformation': ["fill_square_400"]},
  {'transformation': ["rounded_cartoonified_frame"]}
  ])
```

```php
use Cloudinary\Transformation\NamedTransformation;

(new ImageTag('lighthouse_reflection.jpg'))
	->namedTransformation(NamedTransformation::name("fill_square_400"))
	->namedTransformation(NamedTransformation::name("rounded_cartoonified_frame"));
```

```java
cloudinary.url().transformation(new Transformation()
  .named("fill_square_400").chain()
  .named("rounded_cartoonified_frame")).imageTag("lighthouse_reflection.jpg");
```

```ruby
cl_image_tag("lighthouse_reflection.jpg", transformation: [
  {transformation: ["fill_square_400"]},
  {transformation: ["rounded_cartoonified_frame"]}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Named("fill_square_400").Chain()
  .Named("rounded_cartoonified_frame")).BuildImageTag("lighthouse_reflection.jpg")
```

```dart
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_square_400"))
	.namedTransformation(NamedTransformation.name("rounded_cartoonified_frame")));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setNamed("fill_square_400").chain()
  .setNamed("rounded_cartoonified_frame")).generate("lighthouse_reflection.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .named("fill_square_400").chain()
  .named("rounded_cartoonified_frame")).generate("lighthouse_reflection.jpg");
```

```flutter
cloudinary.image('lighthouse_reflection.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_square_400"))
	.namedTransformation(NamedTransformation.name("rounded_cartoonified_frame")));
```

```kotlin
cloudinary.image {
	publicId("lighthouse_reflection.jpg")
	 namedTransformation(NamedTransformation.name("fill_square_400"))
	 namedTransformation(NamedTransformation.name("rounded_cartoonified_frame")) 
}.generate()
```

```jquery
$.cloudinary.image("lighthouse_reflection.jpg", {transformation: [
  {transformation: ["fill_square_400"]},
  {transformation: ["rounded_cartoonified_frame"]}
  ]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("lighthouse_reflection.jpg")
  .namedTransformation(name("fill_square_400"))
  .namedTransformation(name("rounded_cartoonified_frame"));
```

![Applying all 3 named transformations](https://res.cloudinary.com/demo/video/upload/t_round-if-portrait/t_portrait-resize-g_auto/t_logo-overlay/du_10/docs/green_screen_queen.mp4)

```nodejs
cloudinary.video("docs/green_screen_queen", {transformation: [
  {transformation: ["round-if-portrait"]},
  {transformation: ["portrait-resize-g_auto"]},
  {transformation: ["logo-overlay"]},
  {duration: "10"}
  ]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/green_screen_queen.mp4")
  .namedTransformation(name("round-if-portrait"))
  .namedTransformation(name("portrait-resize-g_auto"))
  .namedTransformation(name("logo-overlay"))
  .videoEdit(trim().duration("10.0"));
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/green_screen_queen.mp4")
  .namedTransformation(name("round-if-portrait"))
  .namedTransformation(name("portrait-resize-g_auto"))
  .namedTransformation(name("logo-overlay"))
  .videoEdit(trim().duration("10.0"));
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/green_screen_queen.mp4")
  .namedTransformation(name("round-if-portrait"))
  .namedTransformation(name("portrait-resize-g_auto"))
  .namedTransformation(name("logo-overlay"))
  .videoEdit(trim().duration("10.0"));
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/green_screen_queen.mp4")
  .namedTransformation(name("round-if-portrait"))
  .namedTransformation(name("portrait-resize-g_auto"))
  .namedTransformation(name("logo-overlay"))
  .videoEdit(trim().duration("10.0"));
```

```python
CloudinaryVideo("docs/green_screen_queen").video(transformation=[
  {'transformation': ["round-if-portrait"]},
  {'transformation': ["portrait-resize-g_auto"]},
  {'transformation': ["logo-overlay"]},
  {'duration': "10"}
  ])
```

```php
use Cloudinary\Transformation\NamedTransformation;
use Cloudinary\Transformation\VideoEdit;

(new VideoTag('docs/green_screen_queen.mp4'))
	->namedTransformation(NamedTransformation::name("round-if-portrait"))
	->namedTransformation(NamedTransformation::name("portrait-resize-g_auto"))
	->namedTransformation(NamedTransformation::name("logo-overlay"))
	->videoEdit(VideoEdit::trim()->duration(10.0));
```

```java
cloudinary.url().transformation(new Transformation()
  .named("round-if-portrait").chain()
  .named("portrait-resize-g_auto").chain()
  .named("logo-overlay").chain()
  .duration("10")).videoTag("docs/green_screen_queen");
```

```ruby
cl_video_tag("docs/green_screen_queen", transformation: [
  {transformation: ["round-if-portrait"]},
  {transformation: ["portrait-resize-g_auto"]},
  {transformation: ["logo-overlay"]},
  {duration: "10"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Named("round-if-portrait").Chain()
  .Named("portrait-resize-g_auto").Chain()
  .Named("logo-overlay").Chain()
  .Duration("10")).BuildVideoTag("docs/green_screen_queen")
```

```dart
cloudinary.video('docs/green_screen_queen.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("round-if-portrait"))
	.namedTransformation(NamedTransformation.name("portrait-resize-g_auto"))
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.videoEdit(VideoEdit.trim().duration('10.0')));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setNamed("round-if-portrait").chain()
  .setNamed("portrait-resize-g_auto").chain()
  .setNamed("logo-overlay").chain()
  .setDuration("10")).generate("docs/green_screen_queen.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .named("round-if-portrait").chain()
  .named("portrait-resize-g_auto").chain()
  .named("logo-overlay").chain()
  .duration("10")).resourceType("video").generate("docs/green_screen_queen.mp4");
```

```flutter
cloudinary.video('docs/green_screen_queen.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("round-if-portrait"))
	.namedTransformation(NamedTransformation.name("portrait-resize-g_auto"))
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.videoEdit(VideoEdit.trim().duration('10.0')));
```

```kotlin
cloudinary.video {
	publicId("docs/green_screen_queen.mp4")
	 namedTransformation(NamedTransformation.name("round-if-portrait"))
	 namedTransformation(NamedTransformation.name("portrait-resize-g_auto"))
	 namedTransformation(NamedTransformation.name("logo-overlay"))
	 videoEdit(VideoEdit.trim() { duration(10.0F) }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/green_screen_queen", {transformation: [
  {transformation: ["round-if-portrait"]},
  {transformation: ["portrait-resize-g_auto"]},
  {transformation: ["logo-overlay"]},
  {duration: "10"}
  ]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/green_screen_queen.mp4")
  .namedTransformation(name("round-if-portrait"))
  .namedTransformation(name("portrait-resize-g_auto"))
  .namedTransformation(name("logo-overlay"))
  .videoEdit(trim().duration("10.0"));
```

Chaining transformations can create long URLs, so instead you could define a named transformation that includes a chain of other transformations, including other named transformations. For example, we can create a named transformation that is a composite of the named transformations from the section above. 

It is now simple to specify a single named transformation and apply it to any asset:

![demo_combined named transformation applied to image](https://res.cloudinary.com/demo/image/upload/t_fill_circle_cartoon/sunset_lake.jpg "thumb:w_250")

```nodejs
cloudinary.image("sunset_lake.jpg", {transformation: ["fill_circle_cartoon"]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("sunset_lake.jpg").namedTransformation(
  name("fill_circle_cartoon")
);
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("sunset_lake.jpg").namedTransformation(
  name("fill_circle_cartoon")
);
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("sunset_lake.jpg").namedTransformation(
  name("fill_circle_cartoon")
);
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("sunset_lake.jpg").namedTransformation(
  name("fill_circle_cartoon")
);
```

```python
CloudinaryImage("sunset_lake.jpg").image(transformation=["fill_circle_cartoon"])
```

```php
use Cloudinary\Transformation\NamedTransformation;

(new ImageTag('sunset_lake.jpg'))
	->namedTransformation(NamedTransformation::name("fill_circle_cartoon"));
```

```java
cloudinary.url().transformation(new Transformation().named("fill_circle_cartoon")).imageTag("sunset_lake.jpg");
```

```ruby
cl_image_tag("sunset_lake.jpg", transformation: ["fill_circle_cartoon"])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("fill_circle_cartoon")).BuildImageTag("sunset_lake.jpg")
```

```dart
cloudinary.image('sunset_lake.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_circle_cartoon")));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("fill_circle_cartoon")).generate("sunset_lake.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().named("fill_circle_cartoon")).generate("sunset_lake.jpg");
```

```flutter
cloudinary.image('sunset_lake.jpg').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("fill_circle_cartoon")));
```

```kotlin
cloudinary.image {
	publicId("sunset_lake.jpg")
	 namedTransformation(NamedTransformation.name("fill_circle_cartoon")) 
}.generate()
```

```jquery
$.cloudinary.image("sunset_lake.jpg", {transformation: ["fill_circle_cartoon"]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";

new CloudinaryImage("sunset_lake.jpg").namedTransformation(
  name("fill_circle_cartoon")
);
```

![demo combined named transformation applied to video with variables](https://res.cloudinary.com/demo/video/upload/t_demo-combine-named/du_10/docs/long-boarding-one-surfer.mp4)

```nodejs
cloudinary.video("docs/long-boarding-one-surfer", {transformation: [
  {transformation: ["demo-combine-named"]},
  {duration: "10"}
  ]})
```

```react
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/long-boarding-one-surfer.mp4")
  .namedTransformation(name("demo-combine-named"))
  .videoEdit(trim().duration("10.0"));
```

```vue
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/long-boarding-one-surfer.mp4")
  .namedTransformation(name("demo-combine-named"))
  .videoEdit(trim().duration("10.0"));
```

```angular
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/long-boarding-one-surfer.mp4")
  .namedTransformation(name("demo-combine-named"))
  .videoEdit(trim().duration("10.0"));
```

```js
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/long-boarding-one-surfer.mp4")
  .namedTransformation(name("demo-combine-named"))
  .videoEdit(trim().duration("10.0"));
```

```python
CloudinaryVideo("docs/long-boarding-one-surfer").video(transformation=[
  {'transformation': ["demo-combine-named"]},
  {'duration': "10"}
  ])
```

```php
use Cloudinary\Transformation\NamedTransformation;
use Cloudinary\Transformation\VideoEdit;

(new VideoTag('docs/long-boarding-one-surfer.mp4'))
	->namedTransformation(NamedTransformation::name("demo-combine-named"))
	->videoEdit(VideoEdit::trim()->duration(10.0));
```

```java
cloudinary.url().transformation(new Transformation()
  .named("demo-combine-named").chain()
  .duration("10")).videoTag("docs/long-boarding-one-surfer");
```

```ruby
cl_video_tag("docs/long-boarding-one-surfer", transformation: [
  {transformation: ["demo-combine-named"]},
  {duration: "10"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Named("demo-combine-named").Chain()
  .Duration("10")).BuildVideoTag("docs/long-boarding-one-surfer")
```

```dart
cloudinary.video('docs/long-boarding-one-surfer.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("demo-combine-named"))
	.videoEdit(VideoEdit.trim().duration('10.0')));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setNamed("demo-combine-named").chain()
  .setDuration("10")).generate("docs/long-boarding-one-surfer.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .named("demo-combine-named").chain()
  .duration("10")).resourceType("video").generate("docs/long-boarding-one-surfer.mp4");
```

```flutter
cloudinary.video('docs/long-boarding-one-surfer.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("demo-combine-named"))
	.videoEdit(VideoEdit.trim().duration('10.0')));
```

```kotlin
cloudinary.video {
	publicId("docs/long-boarding-one-surfer.mp4")
	 namedTransformation(NamedTransformation.name("demo-combine-named"))
	 videoEdit(VideoEdit.trim() { duration(10.0F) }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/long-boarding-one-surfer", {transformation: [
  {transformation: ["demo-combine-named"]},
  {duration: "10"}
  ]})
```

```react_native
import { name } from "@cloudinary/url-gen/actions/namedTransformation";
import { trim } from "@cloudinary/url-gen/actions/videoEdit";

new CloudinaryVideo("docs/long-boarding-one-surfer.mp4")
  .namedTransformation(name("demo-combine-named"))
  .videoEdit(trim().duration("10.0"));
```

Where the `fill_circle_cartoon` named transformation is defined as: `t_fill_square_400/t_rounded_cartoonified_frame`. 
### Limitations of named transformations

#### Automatic format

The [automatic format](transformation_reference#f_auto) transformation parameter (`f_auto`) is not effective if used in named transformations. 

When `f_auto` is used in a delivery URL, the CDN layer determines the best format to deliver.  If this parameter is hidden in a named transformation then it is not visible to the CDN. 

You can use `f_auto` together with a named transformation by chaining the components, for example, `t_square/f_auto`.

#### Automatic quality

The [automatic quality](transformation_reference#q_auto) transformation parameter (`q_auto`) is effective in named transformations, except in one situation.

When `q_auto` is used in a delivery URL and the browser sets the `Save-Data` HTTP header to `on` in the request, `q_auto` is translated to `q_auto:eco` at the CDN level. If this parameter is hidden in a named transformation then it is not visible to the CDN, so the default level is applied, `q_auto:good`. 

To accommodate this situation, you may prefer to use `q_auto` together with a named transformation by chaining the components, for example, `t_square/q_auto`.

> **NOTE**: If you explicitly set the type of quality to apply in a named transformation, for example, `q_auto:best`, then there are no concerns as there are no dependencies on the CDN level.

**Learn more**: [Save-Data support](image_optimization#save_data_support)

### Default image placeholder caching

When a requested asset doesn't exist and a [default image](transformation_reference#d_default_image) is delivered, Cloudinary sets stricter cache headers than for regular non-default images: 

* **Default image**: private, with a short max-age (five minutes)
* **Non-default image**: public, with a max-age of 30 days for a `res.cloudinary.com` hostname or one year for a custom hostname. 
  
The shorter max-age causes browsers to check back sooner for the real asset.

If you include the default image parameter (`d_`) inside a named transformation, the stricter cache settings don't apply. To ensure short caching for placeholders, use `d_` directly in the delivery URL, not within a named transformation.

### Automatic width

The [automatic width](transformation_reference#w_auto) transformation parameter (`w_auto`) is not effective if used in named transformations. 

For responsive image solutions, `w_auto` must appear directly in the delivery URL. If it's hidden within a named transformation, it won't be visible to the client or CDN (depending on the solution) and therefore won't take effect.

See [Responsive images using the cloudinary-core JS library](responsive_client_side_js) and [Responsive images using client hints](responsive_server_side_client_hints#automatic_image_width).

### Automatic device pixel ratio

The [automatic device pixel ratio](transformation_reference#dpr_auto) transformation parameter (`dpr_auto`) is not effective if used in named transformations. 

For responsive image solutions, `dpr_auto` must appear directly in the delivery URL. If it's hidden within a named transformation, it won't be visible to the client or CDN (depending on the solution) and therefore won't take effect.

See [Responsive images using the cloudinary-core JS library](responsive_client_side_js) and [Responsive images using client hints](responsive_server_side_client_hints#automatic_pixel_density_detection).


## Named transformation video tutorial

Watch this video tutorial to learn how to create re-usable named transformations with the [Cloudinary Transformation Builder](https://console.cloudinary.com/app/image/transformation_builder) UI.

### Tutorial contents This tutorial presents the following topics. Click a timestamp to jump to that part of the video.

### Using the same transformations over and over?
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media1 :min=0 :sec=05 :player=yt} | If you find yourself using the same transformations repeatedly, you can use named transformations to create a succinct identifier that tells Cloudinary exactly what to do with the asset. 
|

### Open the Transformation Builder
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media1 :min=0 :sec=24 :player=yt} | To get started, expand the **Transformations** option in the menu of the Cloudinary Console. From here, select **Named Transformations** and click **Add New** to launch the Transformation Builder.

### Start adding your transformations 
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media1 :min=0 :sec=37 :player=yt} | Click the **Start Creating** button to initiate your new transformation. You can see the available actions, such as the thumbnail action. In this example, it's set to a width and height of 500px, automatic focus and zoom level of 0.5. Click **Apply and Close** to view the result of that transformation on the preview image.
|

### Save your named transformation
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media1 :min=1 :sec=06 :player=yt} | You can continue adding actions to your transformation but if you're happy, click **Save as Named Transformation** and give your new transformation a name, such as "my-transformation". Click **Save Transformation** to save it, and you'll see the name appear in the top corner.
|

### Use your named transformation
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media1 :min=1 :sec=23 :player=yt} | You can use your new transformation in place of your long transformation string. Remove the existing string from your URL and replace it with `t_my-transformation`. You should have the same result as chaining all the transformations previously. You can use this now to replicate that same transformation on any asset. 
|

## Copying named transformations between product environments

You can copy named transformations from one product environment to another using the Admin API.

1. In the source product environment, list named transformations using [Get transformations](admin_api#get_transformations) with `named=true`.
2. If the response includes `next_cursor`, continue requesting additional pages until all named transformations are returned.
3. In the destination product environment, recreate each named transformation using [Create a named transformation](admin_api#create_a_named_transformation).

### Java example

For Java SDK implementations, this workflow is typically handled by:

* calling `api.transformations(...)` on the source product environment
* iterating through the returned named transformations
* calling `api.createTransformation(...)` on the destination product environment for each transformation you want to copy

```java
Map sourceOptions = new HashMap();
sourceOptions.put("named", true);

ApiResponse result = sourceApi.transformations(sourceOptions);

@SuppressWarnings("unchecked")
List<Map<String, Object>> transformations =
    (List<Map<String, Object>>) result.get("transformations");

for (Map<String, Object> transformation : transformations) {
    String name = (String) transformation.get("name");

    destinationApi.createTransformation(
        name,
        name,
        ObjectUtils.emptyMap()
    );
}
```

If your source response includes a `next_cursor` value, continue requesting additional pages until all named transformations have been processed.

