> ## 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](video_user_defined_variables). For a use-case example demonstrating named transformations with user-defined variables, see [Using variables with named transformations](video_user_defined_variables#using_variables_with_named_transformations).

> **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).

To access the page:

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.
### Working with video transformation templates
> **INFO**:
>
> **Save as Template** and **Load Template** are not available on the Assets Free plan. For upgrade options or more information, [contact us](https://cloudinary.com/contact).

You can save and load [transformation templates](dam_admin_asset_management#transformation_templates) (named transformations) directly from the Transformation Builder when working with video assets. This lets you reuse transformations across videos without recreating them each time.

![Save as Template and Load Template buttons in the Transformation Builder](https://cloudinary-res.cloudinary.com/image/upload/f_auto/q_auto/bo_1px_solid_grey/v1776351603/docs/video_player_studio/named-transformation-template.png "thumb: w_700,dpr_2, width:700, with_url:false, with_code:false, popup:true, conditional: false")

To save the current transformation as a template, click **Save as Template** at the top of the page. In the **Save Template** dialog, enter a unique name and click **Save**. Template names can't duplicate existing template names. After saving, use `t_<name>` when referencing the template in your code. For naming rules, see [creating named transformations](dam_admin_asset_management#creating_named_transformations).

To load a saved template, click **Load Template** at the top of the page and select a template from the drop-down.

> **NOTE**: Loading a template replaces the current transformation in the builder. If you've made edits you want to keep, save them as a template first.

## Named transformation examples

Below are some examples using named transformations that have been defined for the Cloudinary `demo` product environment:

* **round-if-portrait** (defined as `if_ar_lt_1/r_50/if_end`): If the original video's aspect ratio is less than 1 (portrait), round the edges of the video.
  ![named transformation - control quality with variable values](https://res.cloudinary.com/demo/video/upload/t_round-if-portrait/h_300/docs/parrot.mp4)

```nodejs
cloudinary.video("docs/parrot", {transformation: [
  {transformation: ["round-if-portrait"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/parrot.mp4")
  .namedTransformation(name("round-if-portrait"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/parrot.mp4")
  .namedTransformation(name("round-if-portrait"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/parrot.mp4")
  .namedTransformation(name("round-if-portrait"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/parrot.mp4")
  .namedTransformation(name("round-if-portrait"))
  .resize(scale().height(300));
```

```python
CloudinaryVideo("docs/parrot").video(transformation=[
  {'transformation': ["round-if-portrait"]},
  {'height': 300, 'crop': "scale"}
  ])
```

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

(new VideoTag('docs/parrot.mp4'))
	->namedTransformation(NamedTransformation::name("round-if-portrait"))
	->resize(Resize::scale()->height(300));
```

```java
cloudinary.url().transformation(new Transformation()
  .named("round-if-portrait").chain()
  .height(300).crop("scale")).videoTag("docs/parrot");
```

```ruby
cl_video_tag("docs/parrot", transformation: [
  {transformation: ["round-if-portrait"]},
  {height: 300, crop: "scale"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Named("round-if-portrait").Chain()
  .Height(300).Crop("scale")).BuildVideoTag("docs/parrot")
```

```dart
cloudinary.video('docs/parrot.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("round-if-portrait"))
	.resize(Resize.scale().height(300)));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setNamed("round-if-portrait").chain()
  .setHeight(300).setCrop("scale")).generate("docs/parrot.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .named("round-if-portrait").chain()
  .height(300).crop("scale")).resourceType("video").generate("docs/parrot.mp4");
```

```flutter
cloudinary.video('docs/parrot.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("round-if-portrait"))
	.resize(Resize.scale().height(300)));
```

```kotlin
cloudinary.video {
	publicId("docs/parrot.mp4")
	 namedTransformation(NamedTransformation.name("round-if-portrait"))
	 resize(Resize.scale() { height(300) }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/parrot", {transformation: [
  {transformation: ["round-if-portrait"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/parrot.mp4")
  .namedTransformation(name("round-if-portrait"))
  .resize(scale().height(300));
```
* **portrait-resize-g_auto** (defined as `ar_3:4,c_fill,g_auto,h_300`): Fill crop the video to a height of 300 and an aspect ratio of 3:4, automatically retaining focus on the main subject in the cropped video.  
  ![named transformation - resize to portrait with auto-focus](https://res.cloudinary.com/demo/video/upload/eo_6/t_portrait-resize-g_auto/docs/sunglasses.mp4)

```nodejs
cloudinary.video("docs/sunglasses", {transformation: [
  {end_offset: "6"},
  {transformation: ["portrait-resize-g_auto"]}
  ]})
```

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

new CloudinaryVideo("docs/sunglasses.mp4")
  .videoEdit(trim().endOffset("6.0"))
  .namedTransformation(name("portrait-resize-g_auto"));
```

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

new CloudinaryVideo("docs/sunglasses.mp4")
  .videoEdit(trim().endOffset("6.0"))
  .namedTransformation(name("portrait-resize-g_auto"));
```

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

new CloudinaryVideo("docs/sunglasses.mp4")
  .videoEdit(trim().endOffset("6.0"))
  .namedTransformation(name("portrait-resize-g_auto"));
```

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

new CloudinaryVideo("docs/sunglasses.mp4")
  .videoEdit(trim().endOffset("6.0"))
  .namedTransformation(name("portrait-resize-g_auto"));
```

```python
CloudinaryVideo("docs/sunglasses").video(transformation=[
  {'end_offset': "6"},
  {'transformation': ["portrait-resize-g_auto"]}
  ])
```

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

(new VideoTag('docs/sunglasses.mp4'))
	->videoEdit(VideoEdit::trim()->endOffset(6.0))
	->namedTransformation(NamedTransformation::name("portrait-resize-g_auto"));
```

```java
cloudinary.url().transformation(new Transformation()
  .endOffset("6").chain()
  .named("portrait-resize-g_auto")).videoTag("docs/sunglasses");
```

```ruby
cl_video_tag("docs/sunglasses", transformation: [
  {end_offset: "6"},
  {transformation: ["portrait-resize-g_auto"]}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .EndOffset("6").Chain()
  .Named("portrait-resize-g_auto")).BuildVideoTag("docs/sunglasses")
```

```dart
cloudinary.video('docs/sunglasses.mp4').transformation(Transformation()
	.videoEdit(VideoEdit.trim().endOffset('6.0'))
	.namedTransformation(NamedTransformation.name("portrait-resize-g_auto")));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setEndOffset("6").chain()
  .setNamed("portrait-resize-g_auto")).generate("docs/sunglasses.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .endOffset("6").chain()
  .named("portrait-resize-g_auto")).resourceType("video").generate("docs/sunglasses.mp4");
```

```flutter
cloudinary.video('docs/sunglasses.mp4').transformation(Transformation()
	.videoEdit(VideoEdit.trim().endOffset('6.0'))
	.namedTransformation(NamedTransformation.name("portrait-resize-g_auto")));
```

```kotlin
cloudinary.video {
	publicId("docs/sunglasses.mp4")
	 videoEdit(VideoEdit.trim() { endOffset(6.0F) })
	 namedTransformation(NamedTransformation.name("portrait-resize-g_auto")) 
}.generate()
```

```jquery
$.cloudinary.video("docs/sunglasses", {transformation: [
  {end_offset: "6"},
  {transformation: ["portrait-resize-g_auto"]}
  ]})
```

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

new CloudinaryVideo("docs/sunglasses.mp4")
  .videoEdit(trim().endOffset("6.0"))
  .namedTransformation(name("portrait-resize-g_auto"));
```
* **logo-overlay**: (defined as `l_cloudinary_icon_white/o_50/e_brightness:100/w_0.2,fl_relative/fl_layer_apply,g_north_east,y_0.01,x_0.01`): Add a brightened and partially transparent logo to the top right of the video. Scale the logo width to be 20% of the overall video width. 
  ![named transformation - add logo overlay](https://res.cloudinary.com/demo/video/upload/t_logo-overlay/h_300/docs/sunset_waves.mp4)

```nodejs
cloudinary.video("docs/sunset_waves", {transformation: [
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

```python
CloudinaryVideo("docs/sunset_waves").video(transformation=[
  {'transformation': ["logo-overlay"]},
  {'height': 300, 'crop': "scale"}
  ])
```

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

(new VideoTag('docs/sunset_waves.mp4'))
	->namedTransformation(NamedTransformation::name("logo-overlay"))
	->resize(Resize::scale()->height(300));
```

```java
cloudinary.url().transformation(new Transformation()
  .named("logo-overlay").chain()
  .height(300).crop("scale")).videoTag("docs/sunset_waves");
```

```ruby
cl_video_tag("docs/sunset_waves", transformation: [
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Named("logo-overlay").Chain()
  .Height(300).Crop("scale")).BuildVideoTag("docs/sunset_waves")
```

```dart
cloudinary.video('docs/sunset_waves.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.resize(Resize.scale().height(300)));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setNamed("logo-overlay").chain()
  .setHeight(300).setCrop("scale")).generate("docs/sunset_waves.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .named("logo-overlay").chain()
  .height(300).crop("scale")).resourceType("video").generate("docs/sunset_waves.mp4");
```

```flutter
cloudinary.video('docs/sunset_waves.mp4').transformation(Transformation()
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.resize(Resize.scale().height(300)));
```

```kotlin
cloudinary.video {
	publicId("docs/sunset_waves.mp4")
	 namedTransformation(NamedTransformation.name("logo-overlay"))
	 resize(Resize.scale() { height(300) }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/sunset_waves", {transformation: [
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```
  

## Chaining named transformations

You can chain named transformations before or after other transformations. For example, here the `logo-overlay` named transformation is applied after a brightness effect:

  ![named transformation - add logo overlay after brightness](https://res.cloudinary.com/demo/video/upload/e_brightness:20/t_logo-overlay/h_300/docs/sunset_waves.mp4)

```nodejs
cloudinary.video("docs/sunset_waves", {transformation: [
  {effect: "brightness:20"},
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .adjust(brightness().level(20))
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .adjust(brightness().level(20))
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .adjust(brightness().level(20))
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .adjust(brightness().level(20))
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

```python
CloudinaryVideo("docs/sunset_waves").video(transformation=[
  {'effect': "brightness:20"},
  {'transformation': ["logo-overlay"]},
  {'height': 300, 'crop': "scale"}
  ])
```

```php
use Cloudinary\Transformation\Adjust;
use Cloudinary\Transformation\NamedTransformation;
use Cloudinary\Transformation\Resize;

(new VideoTag('docs/sunset_waves.mp4'))
	->adjust(Adjust::brightness()->level(20))
	->namedTransformation(NamedTransformation::name("logo-overlay"))
	->resize(Resize::scale()->height(300));
```

```java
cloudinary.url().transformation(new Transformation()
  .effect("brightness:20").chain()
  .named("logo-overlay").chain()
  .height(300).crop("scale")).videoTag("docs/sunset_waves");
```

```ruby
cl_video_tag("docs/sunset_waves", transformation: [
  {effect: "brightness:20"},
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Effect("brightness:20").Chain()
  .Named("logo-overlay").Chain()
  .Height(300).Crop("scale")).BuildVideoTag("docs/sunset_waves")
```

```dart
cloudinary.video('docs/sunset_waves.mp4').transformation(Transformation()
	.adjust(Adjust.brightness().level(20))
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.resize(Resize.scale().height(300)));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setEffect("brightness:20").chain()
  .setNamed("logo-overlay").chain()
  .setHeight(300).setCrop("scale")).generate("docs/sunset_waves.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .effect("brightness:20").chain()
  .named("logo-overlay").chain()
  .height(300).crop("scale")).resourceType("video").generate("docs/sunset_waves.mp4");
```

```flutter
cloudinary.video('docs/sunset_waves.mp4').transformation(Transformation()
	.adjust(Adjust.brightness().level(20))
	.namedTransformation(NamedTransformation.name("logo-overlay"))
	.resize(Resize.scale().height(300)));
```

```kotlin
cloudinary.video {
	publicId("docs/sunset_waves.mp4")
	 adjust(Adjust.brightness() { level(20) })
	 namedTransformation(NamedTransformation.name("logo-overlay"))
	 resize(Resize.scale() { height(300) }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/sunset_waves", {transformation: [
  {effect: "brightness:20"},
  {transformation: ["logo-overlay"]},
  {height: 300, crop: "scale"}
  ]})
```

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

new CloudinaryVideo("docs/sunset_waves.mp4")
  .adjust(brightness().level(20))
  .namedTransformation(name("logo-overlay"))
  .resize(scale().height(300));
```

You can also chain multiple named transformations. For example, to chain the named transformations defined in the previous section (along with an additional transformation to shorten the video duration):

![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 `demo-combine-named` named transformation is defined as: `t_round-if-portrait/t_portrait-resize-g_auto/t_logo-overlay`. 

 
### 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](video_optimization#save_data_support)

