Skip to content

Commit 5479d5d

Browse files
committed
Update cursorrules, readme and ensure auto gravity is used to display the image
1 parent 669f2ee commit 5479d5d

File tree

3 files changed

+21
-20
lines changed

3 files changed

+21
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ npx create-cloudinary-react
2222
The CLI will prompt you for:
2323
- Project name
2424
- **Cloudinary cloud name** (found in your [dashboard](https://console.cloudinary.com/app/home/dashboard))
25-
- Upload preset (optional - required for uploads, but transformations work without it)
25+
- Unsigned upload preset (optional - required for uploads, but transformations work without it)
2626
- AI coding assistant(s) you're using (Cursor, GitHub Copilot, Claude, etc.)
2727
- Whether to install dependencies
2828
- Whether to start dev server

templates/.cursorrules.template

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
## Official Documentation
66
- **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
1616
- Always consult the official transformation rules when creating transformations
1717
- Use only officially supported parameters from the transformation reference
1818

@@ -141,7 +141,7 @@ cld.image('id').overlay(
141141

142142
// Image overlay (logo/image with resize)
143143
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))))
145145
.position(new Position().gravity(compass('south_east')).offsetX(20).offsetY(20))
146146
);
147147
```
@@ -192,7 +192,7 @@ cld.image('id').overlay(
192192

193193
### Transformation Best Practices
194194
- ✅ 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
196196
- ✅ Use `gravity(auto())` unless user specifies a focal point
197197
- ✅ Same transformation syntax works for both images and videos
198198

@@ -241,10 +241,10 @@ cld.image('id').overlay(
241241
- ✅ **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`.
242242
- ✅ **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`.
243243
- ✅ **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).
245245
- ✅ **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')`.
246246
- ✅ **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.)
248248
- ✅ **Text overlay pattern**: `baseImage.overlay(source(text('Your Text', new TextStyle('Arial', 60).fontWeight('bold')).textColor('white')).position(new Position().gravity(compass('center'))))`.
249249
- ✅ Docs: React Image Transformations and transformation reference for overlay syntax.
250250

@@ -343,7 +343,7 @@ res.json({ signature, timestamp: paramsToSign.timestamp, api_key: process.env.CL
343343
```
344344

345345
- ❌ **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).
347347

348348
### Rules for secure uploads
349349
- ✅ 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
400400
muted
401401
/>
402402
```
403-
- ✅ **Documentation**: https://cloudinary.com/documentation/react_video_transformations
403+
- ✅ **Documentation**: https://cloudinary.com/documentation/react_video_transformations.md
404404

405405
### Cloudinary Video Player (The Player)
406406
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(() => {
437437
}, [cloudName]);
438438
return <div ref={containerRef} />;
439439
```
440-
Docs: https://cloudinary.com/documentation/cloudinary_video_player
440+
Docs: https://cloudinary.com/documentation/cloudinary_video_player.md
441441

442442
### When to Use Which?
443443
- ✅ **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
548548
```
549549

550550
## 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
553553
- ✅ Use `placeholder()` and `lazyload()` plugins together
554554
- ✅ Always add `width` and `height` attributes to `AdvancedImage`
555555
- ✅ Store `public_id` from upload success, not full URL

templates/src/App.tsx.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { fill } from '@cloudinary/url-gen/actions/resize';
44
import { format, quality } from '@cloudinary/url-gen/actions/delivery';
55
import { auto } from '@cloudinary/url-gen/qualifiers/format';
66
import { auto as autoQuality } from '@cloudinary/url-gen/qualifiers/quality';
7+
import { autoGravity } from '@cloudinary/url-gen/qualifiers/gravity';
78
import { cld } from './cloudinary/config';
89
import { UploadWidget } from './cloudinary/UploadWidget';
910
import './App.css';
@@ -26,7 +27,7 @@ function App() {
2627

2728
const displayImage = cld
2829
.image(imageId)
29-
.resize(fill().width(600).height(400))
30+
.resize(fill().width(600).height(400).gravity(autoGravity()))
3031
.delivery(format(auto()))
3132
.delivery(quality(autoQuality()));
3233

0 commit comments

Comments
 (0)