From a274262f3b2ae817ff4066a4f71a2ad7c0f88cd3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 4 Feb 2026 23:57:14 +0000 Subject: [PATCH 01/20] chore(release): 1.0.0-beta.14 [skip ci] # [1.0.0-beta.14](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2026-02-04) ### Bug Fixes * improve upload widget reliability and add video player poster options ([ac51e42](https://github.com/cloudinary-devs/create-cloudinary-react/commit/ac51e420f1b81f2a055bb3fb7e0331841e86b37a)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b89574..42c5220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [1.0.0-beta.14](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2026-02-04) + + +### Bug Fixes + +* improve upload widget reliability and add video player poster options ([ac51e42](https://github.com/cloudinary-devs/create-cloudinary-react/commit/ac51e420f1b81f2a055bb3fb7e0331841e86b37a)) + # [1.0.0-beta.13](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.12...v1.0.0-beta.13) (2026-02-03) diff --git a/package.json b/package.json index 59bff43..beb3b6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.13", + "version": "1.0.0-beta.14", "description": "Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup", "type": "module", "bin": { From 07a8a085686b160387388464a722d90c09cb6805 Mon Sep 17 00:00:00 2001 From: strausr Date: Fri, 6 Feb 2026 08:22:12 -0800 Subject: [PATCH 02/20] fix: use correct CLAUDE.md convention for Claude Code Changed from creating `.claude` and `claude.md` files to the official `CLAUDE.md` convention as documented in Claude Code's official docs. Co-authored-by: Cursor --- cli.js | 3 +-- package-lock.json | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cli.js b/cli.js index dda211c..82f1122 100755 --- a/cli.js +++ b/cli.js @@ -247,8 +247,7 @@ async function main() { } if (aiTools.includes('claude')) { - writeFileSync(join(projectPath, '.claude'), aiRulesContent); - writeFileSync(join(projectPath, 'claude.md'), aiRulesContent); + writeFileSync(join(projectPath, 'CLAUDE.md'), aiRulesContent); } if (aiTools.includes('generic')) { diff --git a/package-lock.json b/package-lock.json index 1d72ba9..9075b29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.12", + "version": "1.0.0-beta.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-cloudinary-react", - "version": "1.0.0-beta.12", + "version": "1.0.0-beta.13", "license": "MIT", "dependencies": { "chalk": "^5.3.0", From fecbe870decc54900cd9ba7fd8861eeeb5fa8f2e Mon Sep 17 00:00:00 2001 From: strausr Date: Tue, 10 Feb 2026 12:58:34 -0800 Subject: [PATCH 03/20] Improve CLI and templates: README env default, conditional upload widget, AI prompt context, save .env note - README: default upload preset line when none supplied; add step to save .env and restart - App: hide upload widget when no upload preset; conditional AI prompts (try uploading vs add preset) - App: default display image to samples/landscapes/beach-boat - CLI: explain AI assistant question (local instruction files); list created files per selection after create - CLI: remove edit/review step and 'no data sent' line per feedback - .cursorrules: save .env then restart for changes to load Co-authored-by: Cursor --- cli.js | 28 ++++++++++++++++++---- package-lock.json | 4 ++-- templates/.cursorrules.template | 2 +- templates/README.md.template | 9 +++---- templates/src/App.tsx.template | 42 +++++++++++++++++++++++---------- 5 files changed, 59 insertions(+), 26 deletions(-) diff --git a/cli.js b/cli.js index 82f1122..4d7243b 100755 --- a/cli.js +++ b/cli.js @@ -72,7 +72,7 @@ async function main() { console.log(chalk.cyan.bold('\n🚀 Cloudinary React + Vite\n')); console.log(chalk.gray('💡 Need a Cloudinary account? Sign up for free: https://cloudinary.com/users/register/free\n')); - answers = await inquirer.prompt([ + const questions = [ { type: 'input', name: 'projectName', @@ -135,7 +135,9 @@ async function main() { { type: 'checkbox', name: 'aiTools', - message: 'Which AI coding assistant(s) are you using? (Select all that apply)', + message: + 'Which AI coding assistant(s) are you using? (Select all that apply)\n' + + chalk.gray(' We’ll add local instruction files so your assistant knows Cloudinary patterns.\n'), choices: [ { name: 'Cursor', value: 'cursor' }, { name: 'GitHub Copilot', value: 'copilot' }, @@ -157,7 +159,9 @@ async function main() { default: false, when: (answers) => answers.installDeps, }, - ]); + ]; + + answers = await inquirer.prompt(questions); } const { projectName, cloudName, uploadPreset, aiTools, installDeps, startDev } = answers; @@ -183,6 +187,9 @@ async function main() { PROJECT_NAME: projectName, CLOUD_NAME: cloudName, UPLOAD_PRESET: uploadPreset || '', + UPLOAD_PRESET_ENV_LINE: uploadPreset + ? `- \`VITE_CLOUDINARY_UPLOAD_PRESET\`: ${uploadPreset}` + : '- `VITE_CLOUDINARY_UPLOAD_PRESET`: (not set - add one for uploads)', }; // Function to copy template file @@ -278,6 +285,18 @@ async function main() { console.log(chalk.green('✅ Project created successfully!\n')); + if (aiTools && aiTools.length > 0) { + console.log(chalk.cyan('📋 AI assistant files created:')); + if (aiTools.includes('cursor')) console.log(chalk.gray(' • Cursor: .cursorrules')); + if (aiTools.includes('copilot')) console.log(chalk.gray(' • GitHub Copilot: .github/copilot-instructions.md')); + if (aiTools.includes('claude')) console.log(chalk.gray(' • Claude: CLAUDE.md')); + if (aiTools.includes('generic')) console.log(chalk.gray(' • Generic: AI_INSTRUCTIONS.md, PROMPT.md')); + if (aiTools.includes('cursor') || aiTools.includes('claude')) { + console.log(chalk.gray(' • MCP (Cursor/Claude): .cursor/mcp.json')); + } + console.log(''); + } + if (!answers.hasUploadPreset) { console.log(chalk.yellow('\n📝 Note: Upload preset not configured')); console.log(chalk.gray(' • Transformations will work with sample images')); @@ -286,7 +305,8 @@ async function main() { console.log(chalk.cyan(' 1. Go to https://console.cloudinary.com/app/settings/upload/presets')); console.log(chalk.cyan(' 2. Click "Add upload preset"')); console.log(chalk.cyan(' 3. Set it to "Unsigned" mode')); - console.log(chalk.cyan(' 4. Add the preset name to your .env file\n')); + console.log(chalk.cyan(' 4. Add the preset name to your .env file')); + console.log(chalk.cyan(' 5. Save the file and restart the dev server so it loads correctly\n')); } if (installDeps) { diff --git a/package-lock.json b/package-lock.json index 9075b29..106a9b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.13", + "version": "1.0.0-beta.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-cloudinary-react", - "version": "1.0.0-beta.13", + "version": "1.0.0-beta.14", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/templates/.cursorrules.template b/templates/.cursorrules.template index 2680dd0..0ae4eb3 100644 --- a/templates/.cursorrules.template +++ b/templates/.cursorrules.template @@ -30,7 +30,7 @@ If the user is **not** using the create-cloudinary-react CLI and only has these Create a `.env` file in the project root with **Vite prefix** (required for client access): - `VITE_CLOUDINARY_CLOUD_NAME=your_cloud_name` (required) - `VITE_CLOUDINARY_UPLOAD_PRESET=your_unsigned_preset_name` (optional; required for unsigned upload widget) -- Restart the dev server after adding or changing `.env`. Use `import.meta.env.VITE_*` in code, not `process.env`. +- Save the `.env` file after editing it, then restart the dev server so changes load correctly. Use `import.meta.env.VITE_*` in code, not `process.env`. **2. Reusable Cloudinary instance (config)** Create a config file (e.g. `src/cloudinary/config.ts`) so the rest of the app can use a single `cld` instance: diff --git a/templates/README.md.template b/templates/README.md.template index 4faa69d..3cec979 100644 --- a/templates/README.md.template +++ b/templates/README.md.template @@ -18,11 +18,7 @@ This project uses Cloudinary for image management. If you don't have a Cloudinar Your `.env` file has been pre-configured with: - `VITE_CLOUDINARY_CLOUD_NAME`: {{CLOUD_NAME}} -{{#UPLOAD_PRESET}} -- `VITE_CLOUDINARY_UPLOAD_PRESET`: {{UPLOAD_PRESET}} -{{/UPLOAD_PRESET}} -{{^UPLOAD_PRESET}} -- `VITE_CLOUDINARY_UPLOAD_PRESET`: (not set - required for uploads) +{{UPLOAD_PRESET_ENV_LINE}} **Note**: Transformations work without an upload preset (using sample images). Uploads require an unsigned upload preset. @@ -31,7 +27,8 @@ To create an unsigned upload preset: 2. Click "Add upload preset" 3. Set it to "Unsigned" mode 4. Add the preset name to your `.env` file -{{/UPLOAD_PRESET}} +5. **Save** the `.env` file and restart the dev server so the new values load correctly. + ## AI Assistant Support diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index 7bde6c9..3989371 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -5,11 +5,13 @@ import { format, quality } from '@cloudinary/url-gen/actions/delivery'; import { auto } from '@cloudinary/url-gen/qualifiers/format'; import { auto as autoQuality } from '@cloudinary/url-gen/qualifiers/quality'; import { autoGravity } from '@cloudinary/url-gen/qualifiers/gravity'; -import { cld } from './cloudinary/config'; +import { cld, uploadPreset } from './cloudinary/config'; import { UploadWidget } from './cloudinary/UploadWidget'; import type { CloudinaryUploadResult } from './cloudinary/UploadWidget'; import './App.css'; +const hasUploadPreset = Boolean(uploadPreset); + function App() { const [uploadedImageId, setUploadedImageId] = useState(null); @@ -24,7 +26,7 @@ function App() { }; // Display uploaded image if available, otherwise show a sample - const imageId = uploadedImageId || 'samples/cloudinary-icon'; + const imageId = uploadedImageId || 'samples/people/bicycle'; const displayImage = cld .image(imageId) @@ -38,14 +40,16 @@ function App() {

Cloudinary React + Vite

This is a ready-to-use development environment with Cloudinary integration.

-
-

Upload an Image

- -
+ {hasUploadPreset && ( +
+

Upload an Image

+ +
+ )}

Display Image

@@ -66,9 +70,21 @@ function App() { Copy and paste one of these prompts into your AI assistant:

    -
  • Create an image gallery with lazy loading and responsive
  • -
  • Create a video player that plays a Cloudinary video
  • -
  • Add image overlays with text or logos
  • + {hasUploadPreset ? ( + <> +
  • Upload an image to my account
  • +
  • Create an image gallery with lazy loading and responsive images
  • +
  • Create a video player that plays a Cloudinary video
  • +
  • Add image overlays with text or logos
  • + + ) : ( + <> +
  • Let's try uploading — help me add an upload preset and upload widget
  • +
  • Create an image gallery with lazy loading and responsive
  • +
  • Create a video player that plays a Cloudinary video
  • +
  • Add image overlays with text or logos
  • + + )}
From 1d7f0c6544f4e94d0c11d8033d46226186a5061c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 10 Feb 2026 21:00:45 +0000 Subject: [PATCH 04/20] chore(release): 1.0.0-beta.15 [skip ci] # [1.0.0-beta.15](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2026-02-10) ### Bug Fixes * use correct CLAUDE.md convention for Claude Code ([07a8a08](https://github.com/cloudinary-devs/create-cloudinary-react/commit/07a8a085686b160387388464a722d90c09cb6805)) ### Features * **analytics:** add CLI feature detection for React SDK ([4dfe495](https://github.com/cloudinary-devs/create-cloudinary-react/commit/4dfe4957bf615e9df08afe729e4f024c02d1cc7f)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42c5220..b76300b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [1.0.0-beta.15](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2026-02-10) + + +### Bug Fixes + +* use correct CLAUDE.md convention for Claude Code ([07a8a08](https://github.com/cloudinary-devs/create-cloudinary-react/commit/07a8a085686b160387388464a722d90c09cb6805)) + + +### Features + +* **analytics:** add CLI feature detection for React SDK ([4dfe495](https://github.com/cloudinary-devs/create-cloudinary-react/commit/4dfe4957bf615e9df08afe729e4f024c02d1cc7f)) + # [1.0.0-beta.14](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2026-02-04) diff --git a/package.json b/package.json index beb3b6f..9b18fb9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.14", + "version": "1.0.0-beta.15", "description": "Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup", "type": "module", "bin": { From fbf01ae696e158cab48feb053a3515bb21453fdd Mon Sep 17 00:00:00 2001 From: strausr Date: Tue, 10 Feb 2026 13:15:25 -0800 Subject: [PATCH 05/20] fix: remove upload question --- templates/src/App.tsx.template | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index 3989371..0955f76 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -72,7 +72,6 @@ function App() {
    {hasUploadPreset ? ( <> -
  • Upload an image to my account
  • Create an image gallery with lazy loading and responsive images
  • Create a video player that plays a Cloudinary video
  • Add image overlays with text or logos
  • From d6c68ddc213fbc18771f26840f33edb805950799 Mon Sep 17 00:00:00 2001 From: eportis-cloudinary Date: Tue, 10 Feb 2026 16:15:11 -0800 Subject: [PATCH 06/20] fix: complete the sentance --- templates/src/App.tsx.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index 0955f76..ff03494 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -79,7 +79,7 @@ function App() { ) : ( <>
  • Let's try uploading — help me add an upload preset and upload widget
  • -
  • Create an image gallery with lazy loading and responsive
  • +
  • Create an image gallery with lazy loading and responsive images
  • Create a video player that plays a Cloudinary video
  • Add image overlays with text or logos
  • From a4ecf5d1d1478d854683a115735fa71f7fb50cea Mon Sep 17 00:00:00 2001 From: strausr Date: Tue, 10 Feb 2026 17:34:45 -0800 Subject: [PATCH 07/20] fix: add copy on click --- package-lock.json | 4 ++-- templates/src/App.css.template | 2 +- templates/src/App.tsx.template | 19 ++++++++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 106a9b2..c8d64fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.14", + "version": "1.0.0-beta.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-cloudinary-react", - "version": "1.0.0-beta.14", + "version": "1.0.0-beta.15", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/templates/src/App.css.template b/templates/src/App.css.template index f16d21e..0daec37 100644 --- a/templates/src/App.css.template +++ b/templates/src/App.css.template @@ -90,7 +90,7 @@ h2 { font-size: 0.9rem; transition: all 0.2s; user-select: text; - cursor: text; + cursor: pointer; } .prompts-list li:hover { diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index ff03494..70e24f4 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -25,6 +25,11 @@ function App() { alert(`Upload failed: ${error.message}`); }; + const copyPrompt = (e: React.MouseEvent) => { + const text = e.currentTarget.textContent ?? ''; + void navigator.clipboard.writeText(text); + }; + // Display uploaded image if available, otherwise show a sample const imageId = uploadedImageId || 'samples/people/bicycle'; @@ -72,16 +77,16 @@ function App() {
      {hasUploadPreset ? ( <> -
    • Create an image gallery with lazy loading and responsive images
    • -
    • Create a video player that plays a Cloudinary video
    • -
    • Add image overlays with text or logos
    • +
    • Create an image gallery with lazy loading and responsive images
    • +
    • Create a video player that plays a Cloudinary video
    • +
    • Add image overlays with text or logos
    • ) : ( <> -
    • Let's try uploading — help me add an upload preset and upload widget
    • -
    • Create an image gallery with lazy loading and responsive images
    • -
    • Create a video player that plays a Cloudinary video
    • -
    • Add image overlays with text or logos
    • +
    • Let's try uploading — help me add an upload preset and upload widget
    • +
    • Create an image gallery with lazy loading and responsive images
    • +
    • Create a video player that plays a Cloudinary video
    • +
    • Add image overlays with text or logos
    • )}
    From d875b10b16a8734a27f8aff96eb981ef4fa10e7a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 11 Feb 2026 01:36:53 +0000 Subject: [PATCH 08/20] chore(release): 1.0.0-beta.16 [skip ci] # [1.0.0-beta.16](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2026-02-11) ### Bug Fixes * add copy on click ([a4ecf5d](https://github.com/cloudinary-devs/create-cloudinary-react/commit/a4ecf5d1d1478d854683a115735fa71f7fb50cea)) * complete the sentance ([d6c68dd](https://github.com/cloudinary-devs/create-cloudinary-react/commit/d6c68ddc213fbc18771f26840f33edb805950799)) * remove upload question ([fbf01ae](https://github.com/cloudinary-devs/create-cloudinary-react/commit/fbf01ae696e158cab48feb053a3515bb21453fdd)) --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b76300b..77dfb28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [1.0.0-beta.16](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2026-02-11) + + +### Bug Fixes + +* add copy on click ([a4ecf5d](https://github.com/cloudinary-devs/create-cloudinary-react/commit/a4ecf5d1d1478d854683a115735fa71f7fb50cea)) +* complete the sentance ([d6c68dd](https://github.com/cloudinary-devs/create-cloudinary-react/commit/d6c68ddc213fbc18771f26840f33edb805950799)) +* remove upload question ([fbf01ae](https://github.com/cloudinary-devs/create-cloudinary-react/commit/fbf01ae696e158cab48feb053a3515bb21453fdd)) + # [1.0.0-beta.15](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2026-02-10) diff --git a/package.json b/package.json index 9b18fb9..076aef4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.15", + "version": "1.0.0-beta.16", "description": "Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup", "type": "module", "bin": { From 9ad35b2351a69bca6d4dcd716b10a1508d5228a8 Mon Sep 17 00:00:00 2001 From: eportis-cloudinary Date: Wed, 11 Feb 2026 13:04:12 -0800 Subject: [PATCH 09/20] feat: prompt copied animation --- templates/src/App.css.template | 65 ++++++++++++++++++++++++++++++++++ templates/src/App.tsx.template | 26 +++++++++----- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/templates/src/App.css.template b/templates/src/App.css.template index 0daec37..b3b36e9 100644 --- a/templates/src/App.css.template +++ b/templates/src/App.css.template @@ -91,6 +91,7 @@ h2 { transition: all 0.2s; user-select: text; cursor: pointer; + position: relative; } .prompts-list li:hover { @@ -98,3 +99,67 @@ h2 { border-left-color: rgba(99, 102, 241, 0.8); transform: translateX(4px); } + +@keyframes wipe-in-out { + 0% { + clip-path: polygon( + 0% 0%, + 0% 100%, + 0% 100%, + 0% 0% + ); + } + 15% { + clip-path: polygon( + 0% 0%, + 0% 100%, + 100% 100%, + 100% 0% + ); + } + 85% { + clip-path: polygon( + 0% 0%, + 0% 100%, + 100% 100%, + 100% 0% + ); + } + 100% { + clip-path: polygon( + 100% 0%, + 100% 100%, + 100% 100%, + 100% 0% + ); + } +} + +.prompts-list li::after { + content: '✓ copied'; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: green; + border-radius: 0.5rem; + visibility: hidden; + padding-top: 0.75em; + padding-left: 1em; + + /* without this it sometimes glitched at the end? */ + clip-path: polygon( + 0% 0%, + 0% 100%, + 0% 100%, + 0% 0% + ); + +} + +.prompts-list li.clicked::after { + visibility: visible; + animation-duration: 1.5s; + animation-name: wipe-in-out; +} diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index 70e24f4..1531daf 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -14,6 +14,7 @@ const hasUploadPreset = Boolean(uploadPreset); function App() { const [uploadedImageId, setUploadedImageId] = useState(null); + const [clickedIds, setClickedIds] = useState(new Set()); const handleUploadSuccess = (result: CloudinaryUploadResult) => { console.log('Upload successful:', result); @@ -25,9 +26,16 @@ function App() { alert(`Upload failed: ${error.message}`); }; - const copyPrompt = (e: React.MouseEvent) => { + const copyPrompt = (e: React.MouseEvent, id: number) => { const text = e.currentTarget.textContent ?? ''; - void navigator.clipboard.writeText(text); + void navigator.clipboard.writeText(text).then(() => { + setClickedIds((prev) => new Set(prev).add(id)); + setTimeout(() => setClickedIds( (prev) => { + const next = new Set(prev); + next.delete(id); + return next; + }), 2000); + }); }; // Display uploaded image if available, otherwise show a sample @@ -77,16 +85,16 @@ function App() {
      {hasUploadPreset ? ( <> -
    • Create an image gallery with lazy loading and responsive images
    • -
    • Create a video player that plays a Cloudinary video
    • -
    • Add image overlays with text or logos
    • +
    • copyPrompt(e, 0)} title="Click to copy" className={ clickedIds.has(0) ? "clicked" : '' }>Create an image gallery with lazy loading and responsive images
    • +
    • copyPrompt(e, 1)} title="Click to copy" className={ clickedIds.has(1) ? "clicked" : '' }>Create a video player that plays a Cloudinary video
    • +
    • copyPrompt(e, 2)} title="Click to copy" className={ clickedIds.has(2) ? "clicked" : '' }>Add image overlays with text or logos
    • ) : ( <> -
    • Let's try uploading — help me add an upload preset and upload widget
    • -
    • Create an image gallery with lazy loading and responsive images
    • -
    • Create a video player that plays a Cloudinary video
    • -
    • Add image overlays with text or logos
    • +
    • copyPrompt(e, 0)} title="Click to copy" className={ clickedIds.has(0) ? "clicked" : '' }>Let's try uploading — help me add an upload preset and upload widget
    • +
    • copyPrompt(e, 1)} title="Click to copy" className={ clickedIds.has(1) ? "clicked" : '' }>Create an image gallery with lazy loading and responsive images
    • +
    • copyPrompt(e, 2)} title="Click to copy" className={ clickedIds.has(2) ? "clicked" : '' }>Create a video player that plays a Cloudinary video
    • +
    • copyPrompt(e, 3)} title="Click to copy" className={ clickedIds.has(3) ? "clicked" : '' }>Add image overlays with text or logos
    • )}
    From bade600ee63de7a7c3d8eec40569f8896f96a7bd Mon Sep 17 00:00:00 2001 From: strausr Date: Wed, 11 Feb 2026 14:31:34 -0800 Subject: [PATCH 10/20] fix: simplified questions into arrays --- templates/src/App.tsx.template | 40 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/templates/src/App.tsx.template b/templates/src/App.tsx.template index 1531daf..7fe7adc 100644 --- a/templates/src/App.tsx.template +++ b/templates/src/App.tsx.template @@ -12,9 +12,20 @@ import './App.css'; const hasUploadPreset = Boolean(uploadPreset); +const PROMPTS_WITH_UPLOAD = [ + 'Create an image gallery with lazy loading and responsive images', + 'Create a video player that plays a Cloudinary video', + 'Add image overlays with text or logos', +]; + +const PROMPTS_WITHOUT_UPLOAD = [ + "Let's try uploading — help me add an upload preset and upload widget", + ...PROMPTS_WITH_UPLOAD, +]; + function App() { const [uploadedImageId, setUploadedImageId] = useState(null); - const [clickedIds, setClickedIds] = useState(new Set()); + const [clickedIds, setClickedIds] = useState(new Set()); const handleUploadSuccess = (result: CloudinaryUploadResult) => { console.log('Upload successful:', result); @@ -26,8 +37,7 @@ function App() { alert(`Upload failed: ${error.message}`); }; - const copyPrompt = (e: React.MouseEvent, id: number) => { - const text = e.currentTarget.textContent ?? ''; + const copyPrompt = (text: string, id: number) => { void navigator.clipboard.writeText(text).then(() => { setClickedIds((prev) => new Set(prev).add(id)); setTimeout(() => setClickedIds( (prev) => { @@ -83,20 +93,16 @@ function App() { Copy and paste one of these prompts into your AI assistant:

      - {hasUploadPreset ? ( - <> -
    • copyPrompt(e, 0)} title="Click to copy" className={ clickedIds.has(0) ? "clicked" : '' }>Create an image gallery with lazy loading and responsive images
    • -
    • copyPrompt(e, 1)} title="Click to copy" className={ clickedIds.has(1) ? "clicked" : '' }>Create a video player that plays a Cloudinary video
    • -
    • copyPrompt(e, 2)} title="Click to copy" className={ clickedIds.has(2) ? "clicked" : '' }>Add image overlays with text or logos
    • - - ) : ( - <> -
    • copyPrompt(e, 0)} title="Click to copy" className={ clickedIds.has(0) ? "clicked" : '' }>Let's try uploading — help me add an upload preset and upload widget
    • -
    • copyPrompt(e, 1)} title="Click to copy" className={ clickedIds.has(1) ? "clicked" : '' }>Create an image gallery with lazy loading and responsive images
    • -
    • copyPrompt(e, 2)} title="Click to copy" className={ clickedIds.has(2) ? "clicked" : '' }>Create a video player that plays a Cloudinary video
    • -
    • copyPrompt(e, 3)} title="Click to copy" className={ clickedIds.has(3) ? "clicked" : '' }>Add image overlays with text or logos
    • - - )} + {(hasUploadPreset ? PROMPTS_WITH_UPLOAD : PROMPTS_WITHOUT_UPLOAD).map((text, i) => ( +
    • copyPrompt(text, i)} + title="Click to copy" + className={clickedIds.has(i) ? 'clicked' : ''} + > + {text} +
    • + ))}
    From 82b2ae0537d6bf5f83b9ef9a8544bb9d9137d4cf Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 12 Feb 2026 05:16:00 +0000 Subject: [PATCH 11/20] chore(release): 1.0.0-beta.17 [skip ci] # [1.0.0-beta.17](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2026-02-12) ### Bug Fixes * simplified questions into arrays ([bade600](https://github.com/cloudinary-devs/create-cloudinary-react/commit/bade600ee63de7a7c3d8eec40569f8896f96a7bd)) ### Features * prompt copied animation ([9ad35b2](https://github.com/cloudinary-devs/create-cloudinary-react/commit/9ad35b2351a69bca6d4dcd716b10a1508d5228a8)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77dfb28..22f023e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [1.0.0-beta.17](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2026-02-12) + + +### Bug Fixes + +* simplified questions into arrays ([bade600](https://github.com/cloudinary-devs/create-cloudinary-react/commit/bade600ee63de7a7c3d8eec40569f8896f96a7bd)) + + +### Features + +* prompt copied animation ([9ad35b2](https://github.com/cloudinary-devs/create-cloudinary-react/commit/9ad35b2351a69bca6d4dcd716b10a1508d5228a8)) + # [1.0.0-beta.16](https://github.com/cloudinary-devs/create-cloudinary-react/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2026-02-11) diff --git a/package.json b/package.json index 076aef4..6b9b975 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudinary-react", - "version": "1.0.0-beta.16", + "version": "1.0.0-beta.17", "description": "Scaffold a Cloudinary React + Vite + TypeScript project with interactive setup", "type": "module", "bin": { From 9db39ee8fc149c748ea422544a79b45a60365f47 Mon Sep 17 00:00:00 2001 From: strausr Date: Fri, 13 Feb 2026 16:01:36 -0800 Subject: [PATCH 12/20] fix: update video player example --- templates/.cursorrules.template | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/.cursorrules.template b/templates/.cursorrules.template index 0ae4eb3..c95f311 100644 --- a/templates/.cursorrules.template +++ b/templates/.cursorrules.template @@ -420,7 +420,8 @@ Use when the user asks for a **video player** (styled UI, controls, playlists). **Rule: imperative element only.** Do **not** pass a React-managed `