|
4 | 4 |
|
5 | 5 | ## Official Documentation |
6 | 6 | - **Transformation Rules**: https://cloudinary.com/documentation/cloudinary_transformation_rules.md |
7 | | -- **Transformation Reference**: https://cloudinary.com/documentation/transformation_reference |
8 | | -- **React Image Transformations & Plugins**: https://cloudinary.com/documentation/react_image_transformations#plugins |
9 | | -- **React Video Transformations**: https://cloudinary.com/documentation/react_video_transformations |
10 | | -- **Cloudinary Video Player** (standalone player): https://cloudinary.com/documentation/cloudinary_video_player |
11 | | -- **Video Player React Tutorial**: https://cloudinary.com/documentation/video_player_react_tutorial#banner |
12 | | -- **Upload Widget (signed uploads)**: https://cloudinary.com/documentation/upload_widget#signed_uploads |
13 | | -- **Upload assets in Next.js (backend signature)**: https://cloudinary.com/documentation/upload_assets_in_nextjs_tutorial |
14 | | -- **Cloudinary Node.js SDK (server-side signing)** — use **v2**: `import { v2 as cloudinary } from 'cloudinary'`; do not use v1 (e.g. 1.47.0). https://cloudinary.com/documentation/node_integration |
15 | | -- **React Native image and video upload (signed)**: https://cloudinary.com/documentation/react_native_image_and_video_upload#signed_upload |
| 7 | +- **Transformation Reference**: https://cloudinary.com/documentation/transformation_reference.md |
| 8 | +- **React Image Transformations & Plugins**: https://cloudinary.com/documentation/react_image_transformations.md#plugins |
| 9 | +- **React Video Transformations**: https://cloudinary.com/documentation/react_video_transformations.md |
| 10 | +- **Cloudinary Video Player** (standalone player): https://cloudinary.com/documentation/cloudinary_video_player.md |
| 11 | +- **Video Player React Tutorial**: https://cloudinary.com/documentation/video_player_react_tutorial.md |
| 12 | +- **Upload Widget (signed uploads)**: https://cloudinary.com/documentation/upload_widget.md#signed_uploads |
| 13 | +- **Upload assets in Next.js (backend signature)**: https://cloudinary.com/documentation/upload_assets_in_nextjs_tutorial.md |
| 14 | +- **Cloudinary Node.js SDK (server-side signing)** — use **v2**: `import { v2 as cloudinary } from 'cloudinary'`; do not use v1 (e.g. 1.47.0). https://cloudinary.com/documentation/node_integration.md |
| 15 | +- **React Native image and video upload (signed)**: https://cloudinary.com/documentation/react_native_image_and_video_upload.md#signed_upload |
16 | 16 | - Always consult the official transformation rules when creating transformations |
17 | 17 | - Use only officially supported parameters from the transformation reference |
18 | 18 |
|
@@ -141,7 +141,7 @@ cld.image('id').overlay( |
141 | 141 |
|
142 | 142 | // Image overlay (logo/image with resize) |
143 | 143 | cld.image('id').overlay( |
144 | | - source(image('logo').transformation(new Transformation().resize(scale().width(100).height(100)))) |
| 144 | + source(image('logo').transformation(new Transformation().resize(scale().width(100)))) |
145 | 145 | .position(new Position().gravity(compass('south_east')).offsetX(20).offsetY(20)) |
146 | 146 | ); |
147 | 147 | ``` |
@@ -192,7 +192,7 @@ cld.image('id').overlay( |
192 | 192 |
|
193 | 193 | ### Transformation Best Practices |
194 | 194 | - ✅ Format and quality must use separate `.delivery()` calls |
195 | | -- ✅ Always end with auto format/quality: `.delivery(format(auto())).delivery(quality(autoQuality()))` |
| 195 | +- ✅ Always end with auto format/quality: `.delivery(format(auto())).delivery(quality(autoQuality()))` unless user specifies a particular format or quality |
196 | 196 | - ✅ Use `gravity(auto())` unless user specifies a focal point |
197 | 197 | - ✅ Same transformation syntax works for both images and videos |
198 | 198 |
|
@@ -241,10 +241,10 @@ cld.image('id').overlay( |
241 | 241 | - ✅ **When the user asks for image overlays with text or logos**: Use `@cloudinary/url-gen` overlay APIs. Copy imports and patterns from the **"Import reference"** table and **"Canonical overlay block"** in these rules. Do not import `text` or `image` from `actions/overlay` — they are from **`qualifiers/source`**; only `source` is from `actions/overlay`. |
242 | 242 | - ✅ **Import** `source` from `actions/overlay`; **`text` and `image` from `qualifiers/source`**. Also: `Position` from `qualifiers/position`, `TextStyle` from `qualifiers/textStyle`, `compass` from `qualifiers/gravity`, `Transformation` from `transformation/Transformation`, `scale` from `actions/resize`. |
243 | 243 | - ✅ **compass()** takes **string** values, with **underscores**: `compass('center')`, `compass('south_east')`, `compass('north_west')`. ❌ WRONG: `compass(southEast)` or `'southEast'` (no camelCase). |
244 | | -- ✅ **Overlay image**: Use `new Transformation()` **inside** `.transformation()`: `image('logo').transformation(new Transformation().resize(scale().width(100).height(100)))`. ❌ WRONG: `image('logo').transformation().resize(...)` (`.transformation()` does not return a chainable object). |
| 244 | +- ✅ **Overlay image**: Use `new Transformation()` **inside** `.transformation()`: `image('logo').transformation(new Transformation().resize(scale().width(100)))`. ❌ WRONG: `image('logo').transformation().resize(...)` (`.transformation()` does not return a chainable object). |
245 | 245 | - ✅ **Text overlay**: `fontWeight` goes on **TextStyle**: `new TextStyle('Arial', 60).fontWeight('bold')`. `textColor` goes on the **text source** (chained after `text(...)`): `text('Hello', new TextStyle('Arial', 60)).textColor('white')`. |
246 | 246 | - ✅ **Position** is chained **after** `source(...)`, not inside: `source(image('logo').transformation(...)).position(new Position().gravity(compass('south_east')).offsetX(20).offsetY(20))`. |
247 | | -- ✅ **Image overlay pattern**: `baseImage.overlay(source(image('id').transformation(new Transformation().resize(scale().width(100).height(100)))).position(new Position().gravity(compass('south_east')).offsetX(20).offsetY(20)))`. (Import `scale` from `@cloudinary/url-gen/actions/resize` if needed.) |
| 247 | +- ✅ **Image overlay pattern**: `baseImage.overlay(source(image('id').transformation(new Transformation().resize(scale().width(100)))).position(new Position().gravity(compass('south_east')).offsetX(20).offsetY(20)))`. (Import `scale` from `@cloudinary/url-gen/actions/resize` if needed.) |
248 | 248 | - ✅ **Text overlay pattern**: `baseImage.overlay(source(text('Your Text', new TextStyle('Arial', 60).fontWeight('bold')).textColor('white')).position(new Position().gravity(compass('center'))))`. |
249 | 249 | - ✅ Docs: React Image Transformations and transformation reference for overlay syntax. |
250 | 250 |
|
@@ -343,7 +343,7 @@ res.json({ signature, timestamp: paramsToSign.timestamp, api_key: process.env.CL |
343 | 343 | ``` |
344 | 344 |
|
345 | 345 | - ❌ **Avoid `signatureEndpoint`** — it may not be called reliably by all widget versions. Prefer the `uploadSignature` function. |
346 | | -- ✅ Docs: [Upload widget — signed uploads](https://cloudinary.com/documentation/upload_widget#signed_uploads), [Upload assets in Next.js](https://cloudinary.com/documentation/upload_assets_in_nextjs_tutorial). |
| 346 | +- ✅ Docs: [Upload widget — signed uploads](https://cloudinary.com/documentation/upload_widget.md#signed_uploads), [Upload assets in Next.js](https://cloudinary.com/documentation/upload_assets_in_nextjs_tutorial.md). |
347 | 347 |
|
348 | 348 | ### Rules for secure uploads |
349 | 349 | - ✅ Use a **signed** upload preset (dashboard → Upload presets → Signed). Do not use an unsigned preset when the user wants secure uploads. **Default:** Accounts have a built-in signed preset `ml_default` — use it if the user hasn't created their own (they can delete `ml_default`, in which case they must create a signed preset in the dashboard). |
@@ -400,7 +400,7 @@ res.json({ signature, timestamp: paramsToSign.timestamp, api_key: process.env.CL |
400 | 400 | muted |
401 | 401 | /> |
402 | 402 | ``` |
403 | | -- ✅ **Documentation**: https://cloudinary.com/documentation/react_video_transformations |
| 403 | +- ✅ **Documentation**: https://cloudinary.com/documentation/react_video_transformations.md |
404 | 404 |
|
405 | 405 | ### Cloudinary Video Player (The Player) |
406 | 406 | Use when the user asks for a **video player** (styled UI, controls, playlists). For just **displaying** a video, use AdvancedVideo instead. |
@@ -437,7 +437,7 @@ useLayoutEffect(() => { |
437 | 437 | }, [cloudName]); |
438 | 438 | return <div ref={containerRef} />; |
439 | 439 | ``` |
440 | | -Docs: https://cloudinary.com/documentation/cloudinary_video_player |
| 440 | +Docs: https://cloudinary.com/documentation/cloudinary_video_player.md |
441 | 441 |
|
442 | 442 | ### When to Use Which? |
443 | 443 | - ✅ **Use AdvancedVideo** when: User wants to **display** or **show** a video (no full player). It just displays a video with transformations. |
@@ -548,8 +548,8 @@ Docs: https://cloudinary.com/documentation/cloudinary_video_player |
548 | 548 | ``` |
549 | 549 |
|
550 | 550 | ## Best Practices |
551 | | -- ✅ Always use `fill()` resize for responsive images |
552 | | -- ✅ Always end transformations with `.delivery(format(auto())).delivery(quality(autoQuality()))` |
| 551 | +- ✅ Always use `fill()` resize with automatic gravity for responsive images |
| 552 | +- ✅ Always end transformations with `.delivery(format(auto())).delivery(quality(autoQuality()))` unless the user specifies a format or quality |
553 | 553 | - ✅ Use `placeholder()` and `lazyload()` plugins together |
554 | 554 | - ✅ Always add `width` and `height` attributes to `AdvancedImage` |
555 | 555 | - ✅ Store `public_id` from upload success, not full URL |
|
0 commit comments