> ## Documentation Index
> This page is part of the Image and Video APIs product. Fetch the complete documentation index for Image and Video APIs at: https://cloudinary.com/documentation/llms-image-and-video-apis.txt?referrer=docpage and then use it to discover all relevant pages before exploring further.
> If your task extends beyond this product, fetch the top-level index covering all Cloudinary products and topics at: https://cloudinary.com/documentation/llms.txt?referrer=docpage

# Placing layers on images


[underlays]: image_layer_watermarking#image_underlays
[special_layer_applications]: image_layer_watermarking#special_layer_applications
[layer_placement]: image_layer_placement
[layer_transformations]: image_layer_transformations
[styling_parameters]: image_text_layers#styling_parameters
[text_layer_options]: image_text_layers#text_layer_options
[embedding_in_SDKs]: image_transformations#embedding_images_in_web_pages_using_sdks


Cloudinary allows you to dynamically add layers to specific locations within your images, where the new layers are added over the base image as overlays, and can also be easily transformed to suit your needs. There are multiple options for adding a new layer to a base image, either an image uploaded to Cloudinary, a remote image, or a text string. 

Image layers can also be added as [underlays][underlays] instead, and there are [special layer applications][special_layer_applications] for using layers in combination with other Cloudinary transformations.

Here are examples of some popular use cases that you can accomplish using layers (combined with other transformations). Click each image to see the URL parameters applied in each case:

Brand or watermark your images

Hide all detected faces

Add personalized text

Displace imageson products

> **NOTE**: This page describes Cloudinary transformations that apply layers to a specified base image. This differs from delivering images where the [original source file has layers](paged_and_layered_media) that you might reference in a transformation.

This page covers the layer syntax and the overlay types you can apply. To learn how to position layers, see [Layer placement](image_layer_placement). For text options, see [Text layer options](image_text_layers). For transformations and relative sizing, see [Transforming layers](image_layer_transformations). For underlays, watermarking, and special effects, see [Underlays, watermarking, and special effects](image_layer_watermarking).

## Layer transformation syntax

In its most simple form, adding a layer over the base image takes following URL syntax:

```
l_<public id of overlay>/fl_layer_apply
```

The `layer` parameter is in its own URL component and starts the overlay definition (similar to an open bracket). The `layer_apply` flag is in a separate component that closes the definition (similar to a closing bracket) and instructs Cloudinary to place it.

> **NOTE**: Replace any forward slashes in the public ID of the overlay with colons.

You can enhance your layer both by controlling where and how it's [placed][layer_placement] on the base image using **gravity**, **offset** and other placement qualifiers, and by applying [transformations][layer_transformations] to the layered asset, using the following general URL syntax.

```
l_<public_id of layer>/<optional layer transformations>/fl_layer_apply,<optional placement qualifiers>
```

### Authenticated or private layers

You can add image overlays that are set to `authenticated` or `private` by modifying the syntax:

* For private layers: `l_private:<public_id of layer>`
* For authenticated layers: `l_authenticated:<public_id of layer>`

> **INFO**: You can only add image overlays that are set to `authenticated` or `private` if you also sign the whole URL (no separate signature is required for the overlay part). See the [Media access control](control_access_to_media) documentation for more details on delivering private and authenticated assets.

## Image overlays

The default overlay type is an image. For example, adding an overlay of a logo to a base image (`l_docs:logo-semi-opaque/fl_layer_apply`):

![Image with overlay](https://res.cloudinary.com/demo/image/upload/l_docs:logo-semi-opaque/fl_layer_apply/docs/suit_man_forest "thumb: w_500")

```nodejs
cloudinary.image("docs/suit_man_forest", {transformation: [
  {overlay: "docs:logo-semi-opaque"},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/suit_man_forest").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/suit_man_forest").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/suit_man_forest").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/suit_man_forest").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```python
CloudinaryImage("docs/suit_man_forest").image(transformation=[
  {'overlay': "docs:logo-semi-opaque"},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;

(new ImageTag('docs/suit_man_forest'))
	->overlay(Overlay::source(
	Source::image("docs/logo-semi-opaque")));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("docs:logo-semi-opaque")).chain()
  .flags("layer_apply")).imageTag("docs/suit_man_forest");
```

```ruby
cl_image_tag("docs/suit_man_forest", transformation: [
  {overlay: "docs:logo-semi-opaque"},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("docs:logo-semi-opaque")).Chain()
  .Flags("layer_apply")).BuildImageTag("docs/suit_man_forest")
```

```dart
cloudinary.image('docs/suit_man_forest').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("docs:logo-semi-opaque").chain()
  .setFlags("layer_apply")).generate("docs/suit_man_forest")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("docs:logo-semi-opaque")).chain()
  .flags("layer_apply")).generate("docs/suit_man_forest");
```

```flutter
cloudinary.image('docs/suit_man_forest').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))));
```

```kotlin
cloudinary.image {
	publicId("docs/suit_man_forest")
	 overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))) 
}.generate()
```

```jquery
$.cloudinary.image("docs/suit_man_forest", {transformation: [
  {overlay: new cloudinary.Layer().publicId("docs:logo-semi-opaque")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/suit_man_forest").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

![Video with image overlay](https://res.cloudinary.com/demo/video/upload/l_docs:logo-semi-opaque/fl_layer_apply/glide-over-coastal-beach.mp4 "thumb: w_600")

```nodejs
cloudinary.video("glide-over-coastal-beach", {transformation: [
  {overlay: "docs:logo-semi-opaque"},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("glide-over-coastal-beach.mp4").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("glide-over-coastal-beach.mp4").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("glide-over-coastal-beach.mp4").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("glide-over-coastal-beach.mp4").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

```python
CloudinaryVideo("glide-over-coastal-beach").video(transformation=[
  {'overlay': "docs:logo-semi-opaque"},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;

(new VideoTag('glide-over-coastal-beach.mp4'))
	->overlay(Overlay::source(
	Source::image("docs/logo-semi-opaque")));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("docs:logo-semi-opaque")).chain()
  .flags("layer_apply")).videoTag("glide-over-coastal-beach");
```

```ruby
cl_video_tag("glide-over-coastal-beach", transformation: [
  {overlay: "docs:logo-semi-opaque"},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("docs:logo-semi-opaque")).Chain()
  .Flags("layer_apply")).BuildVideoTag("glide-over-coastal-beach")
```

```dart
cloudinary.video('glide-over-coastal-beach.mp4').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setOverlay("docs:logo-semi-opaque").chain()
  .setFlags("layer_apply")).generate("glide-over-coastal-beach.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("docs:logo-semi-opaque")).chain()
  .flags("layer_apply")).resourceType("video").generate("glide-over-coastal-beach.mp4");
```

```flutter
cloudinary.video('glide-over-coastal-beach.mp4').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))));
```

```kotlin
cloudinary.video {
	publicId("glide-over-coastal-beach.mp4")
	 overlay(Overlay.source(
	Source.image("docs/logo-semi-opaque"))) 
}.generate()
```

```jquery
$.cloudinary.video("glide-over-coastal-beach", {transformation: [
  {overlay: new cloudinary.Layer().publicId("docs:logo-semi-opaque")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { image } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("glide-over-coastal-beach.mp4").overlay(
  source(image("docs/logo-semi-opaque"))
);
```

> **INFO**: If the public ID of an image includes slashes (e.g., the public ID of an image is `animals/dog`), replace the slashes with colons when using the image as an overlay (e.g., the public ID of the overlay image becomes `animals:dog` when used as an overlay).

**See full syntax**: [l_\<image id\>](transformation_reference#l_image_id) in the _Transformation Reference_.

**Try it out**: [Layers](https://console.cloudinary.com/app/image/playground/layers?media=image&collection=image&sample=me%2Flayers-fashion-1.jpeg&variant=banner&imageCompass=north_east&textCompass=center&text=NEW+COLLECTION).

## Remote image overlays

Use a remote image (an image not stored in your Cloudinary product environment) as an overlay by adding the `fetch` (or `url` for some SDKs) property of the `layer` parameter ( `l_fetch:` in URLs) and the base64 encoded URL of the remote image.

> **NOTE**:
>
> You can only fetch remote **images** for overlays. Fetching remote videos or audio files for use as overlays isn't supported.

The general URL syntax for adding a remote image as an overlay takes the following form:

```
l_fetch:<URL of overlay>/<optional transformations>/fl_layer_apply,<optional placement qualifiers>
```

For example, adding an overlay of the remote image `https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png` to the base image.

![Image with remote overlay](https://res.cloudinary.com/demo/image/upload/l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply/docs/office_desk "thumb: w_500")

```nodejs
cloudinary.image("docs/office_desk", {transformation: [
  {overlay: {url: "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/office_desk").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/office_desk").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/office_desk").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/office_desk").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```python
CloudinaryImage("docs/office_desk").image(transformation=[
  {'overlay': {'url': "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;

(new ImageTag('docs/office_desk'))
	->overlay(Overlay::source(
	Source::fetch("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).chain()
  .flags("layer_apply")).imageTag("docs/office_desk");
```

```ruby
cl_image_tag("docs/office_desk", transformation: [
  {overlay: {url: "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new FetchLayer("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).Chain()
  .Flags("layer_apply")).BuildImageTag("docs/office_desk")
```

```dart
cloudinary.image('docs/office_desk').transformation(Transformation()
	.addTransformation("l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw").chain()
  .setFlags("layer_apply")).generate("docs/office_desk")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).chain()
  .flags("layer_apply")).generate("docs/office_desk");
```

```flutter
cloudinary.image('docs/office_desk').transformation(Transformation()
	.addTransformation("l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply"));
```

```kotlin
cloudinary.image {
	publicId("docs/office_desk")
	 overlay(Overlay.source(
	Source.fetch("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"))) 
}.generate()
```

```jquery
$.cloudinary.image("docs/office_desk", {transformation: [
  {overlay: new cloudinary.FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryImage("docs/office_desk").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

![Video with remote overlay](https://res.cloudinary.com/demo/video/upload/l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply/blue_sports_car.mp4 "thumb: w_500")

```nodejs
cloudinary.video("blue_sports_car", {transformation: [
  {overlay: {url: "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("blue_sports_car.mp4").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("blue_sports_car.mp4").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("blue_sports_car.mp4").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("blue_sports_car.mp4").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

```python
CloudinaryVideo("blue_sports_car").video(transformation=[
  {'overlay': {'url': "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;

(new VideoTag('blue_sports_car.mp4'))
	->overlay(Overlay::source(
	Source::fetch("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).chain()
  .flags("layer_apply")).videoTag("blue_sports_car");
```

```ruby
cl_video_tag("blue_sports_car", transformation: [
  {overlay: {url: "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"}},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Overlay(new FetchLayer("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).Chain()
  .Flags("layer_apply")).BuildVideoTag("blue_sports_car")
```

```dart
cloudinary.video('blue_sports_car.mp4').transformation(Transformation()
	.addTransformation("l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setOverlay("fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw").chain()
  .setFlags("layer_apply")).generate("blue_sports_car.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")).chain()
  .flags("layer_apply")).resourceType("video").generate("blue_sports_car.mp4");
```

```flutter
cloudinary.video('blue_sports_car.mp4').transformation(Transformation()
	.addTransformation("l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvbG9nb3MvY2xvdWRpbmFyeV9pY29uX3doaXRlLnBuZw/fl_layer_apply"));
```

```kotlin
cloudinary.video {
	publicId("blue_sports_car.mp4")
	 overlay(Overlay.source(
	Source.fetch("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"))) 
}.generate()
```

```jquery
$.cloudinary.video("blue_sports_car", {transformation: [
  {overlay: new cloudinary.FetchLayer().url("https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fetch } from "@cloudinary/url-gen/qualifiers/source";

new CloudinaryVideo("blue_sports_car.mp4").overlay(
  source(
    fetch(
      "https://res.cloudinary.com/demo/image/upload/logos/cloudinary_icon_white.png"
    )
  )
);
```

> **NOTE**: The Cloudinary SDKs automatically generate a base64 encoded URL for a given HTTP/S URL, but if you generate the delivery URL in your own code, then you'll need to supply the fetch URL in base64 encoding with padding.

**See full syntax**: [l_fetch](transformation_reference#l_fetch) in the _Transformation Reference_.
## Text overlays

Add a text overlay over the base image with the `text` property of the `layer` parameter ( `l_text:` in URLs). The parameter also requires specifying font family and size (separated with an underscore and followed by a colon), and the text string to display. The general URL syntax for adding a text layer takes the following form:

```
l_text:<text styling options>/<optional transformations>/fl_layer_apply,<optional placement qualifiers>
```

In addition to the required font and size styling values, you can optionally specify a variety of other CSS-like [styling parameters][styling_parameters] and to further customize your text layers by specifying text color, adding line breaks, emojis and other special characters, and other [text layer options][text_layer_options].

Cloudinary first generates an image from the text definition and then overlays it like any other image overlay, and thus supports all the same [transformations][layer_transformations] that any image overlay supports.

For example, to overlay the text string "Coffee" in the Arial font with a size of 80 pixels (`l_text:Arial_80:Coffee/fl_layer_apply`):

![Adding dynamic text to image](https://res.cloudinary.com/demo/image/upload/l_text:Arial_80:Coffee/fl_layer_apply/docs/cappuccino.jpg "thumb: w_500")

```nodejs
cloudinary.image("docs/cappuccino.jpg", {transformation: [
  {overlay: {font_family: "Arial", font_size: 80, text: "Coffee"}},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryImage("docs/cappuccino.jpg").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryImage("docs/cappuccino.jpg").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryImage("docs/cappuccino.jpg").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryImage("docs/cappuccino.jpg").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```python
CloudinaryImage("docs/cappuccino.jpg").image(transformation=[
  {'overlay': {'font_family': "Arial", 'font_size': 80, 'text': "Coffee"}},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\TextStyle;

(new ImageTag('docs/cappuccino.jpg'))
	->overlay(Overlay::source(
	Source::text("Coffee",(new TextStyle("Arial",80)))));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")).chain()
  .flags("layer_apply")).imageTag("docs/cappuccino.jpg");
```

```ruby
cl_image_tag("docs/cappuccino.jpg", transformation: [
  {overlay: {font_family: "Arial", font_size: 80, text: "Coffee"}},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(80).Text("Coffee")).Chain()
  .Flags("layer_apply")).BuildImageTag("docs/cappuccino.jpg")
```

```dart
cloudinary.image('docs/cappuccino.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80:Coffee/fl_layer_apply"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("text:Arial_80:Coffee").chain()
  .setFlags("layer_apply")).generate("docs/cappuccino.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")).chain()
  .flags("layer_apply")).generate("docs/cappuccino.jpg");
```

```flutter
cloudinary.image('docs/cappuccino.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80:Coffee/fl_layer_apply"));
```

```kotlin
cloudinary.image {
	publicId("docs/cappuccino.jpg")
	 overlay(Overlay.source(
	Source.text("Coffee",TextStyle("Arial",80)))) 
}.generate()
```

```jquery
$.cloudinary.image("docs/cappuccino.jpg", {transformation: [
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryImage("docs/cappuccino.jpg").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

![Adding dynamic text to video](https://res.cloudinary.com/demo/video/upload/l_text:Arial_80:Coffee/fl_layer_apply/coffee_drinking.mp4 "thumb: w_500")

```nodejs
cloudinary.video("coffee_drinking", {transformation: [
  {overlay: {font_family: "Arial", font_size: 80, text: "Coffee"}},
  {flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryVideo("coffee_drinking.mp4").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryVideo("coffee_drinking.mp4").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryVideo("coffee_drinking.mp4").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryVideo("coffee_drinking.mp4").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

```python
CloudinaryVideo("coffee_drinking").video(transformation=[
  {'overlay': {'font_family': "Arial", 'font_size': 80, 'text': "Coffee"}},
  {'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\TextStyle;

(new VideoTag('coffee_drinking.mp4'))
	->overlay(Overlay::source(
	Source::text("Coffee",(new TextStyle("Arial",80)))));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")).chain()
  .flags("layer_apply")).videoTag("coffee_drinking");
```

```ruby
cl_video_tag("coffee_drinking", transformation: [
  {overlay: {font_family: "Arial", font_size: 80, text: "Coffee"}},
  {flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(80).Text("Coffee")).Chain()
  .Flags("layer_apply")).BuildVideoTag("coffee_drinking")
```

```dart
cloudinary.video('coffee_drinking.mp4').transformation(Transformation()
	.addTransformation("l_text:Arial_80:Coffee/fl_layer_apply"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setOverlay("text:Arial_80:Coffee").chain()
  .setFlags("layer_apply")).generate("coffee_drinking.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")).chain()
  .flags("layer_apply")).resourceType("video").generate("coffee_drinking.mp4");
```

```flutter
cloudinary.video('coffee_drinking.mp4').transformation(Transformation()
	.addTransformation("l_text:Arial_80:Coffee/fl_layer_apply"));
```

```kotlin
cloudinary.video {
	publicId("coffee_drinking.mp4")
	 overlay(Overlay.source(
	Source.text("Coffee",TextStyle("Arial",80)))) 
}.generate()
```

```jquery
$.cloudinary.video("coffee_drinking", {transformation: [
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).text("Coffee")},
  {flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";

new CloudinaryVideo("coffee_drinking.mp4").overlay(
  source(text("Coffee", new TextStyle("Arial", 80)))
);
```

**See full syntax**: [l_text](transformation_reference#l_text) in the _Transformation Reference_.

**Try it out**: [Layers](https://console.cloudinary.com/app/image/playground/layers?media=image&collection=image&sample=me%2Flayers-fashion-1.jpeg&variant=banner&imageCompass=north_east&textCompass=center&text=NEW+COLLECTION).

> **READING**:
>
> * [Layer placement](image_layer_placement): Position layers using gravity, offsets, and overflow behavior.

> * [Text layer options](image_text_layers): Text styling, color, multi-line text, and special characters.

> * [Transforming layers](image_layer_transformations): Apply transformations, multiple overlays, and relative sizing to layers.

> * [Underlays, watermarking, and special effects](image_layer_watermarking): Image underlays, watermarking, tiling, and special layer applications.
