@netlify/agent-runner-cli 1.69.2 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,244 @@
1
+ ---
2
+ name: netlify-image-cdn
3
+ description: Transform and optimize images on-demand using Netlify Image CDN. Use when implementing responsive images, format conversion, resizing, cropping, or dynamic image optimization without build-time processing.
4
+ ---
5
+
6
+ # Netlify Image CDN
7
+
8
+ Netlify Image CDN transforms and optimizes images on demand at the edge without impacting build times. It handles
9
+ content negotiation to serve the most efficient format and caches transformed images for fast delivery.
10
+
11
+ ## Quick Start
12
+
13
+ All Netlify projects have a `/.netlify/images` route without any additional enablement. Use it with query parameters to
14
+ transform any image:
15
+
16
+ ```html
17
+ <!-- Resize to 400px wide, convert to WebP -->
18
+ <img src="/.netlify/images?url=/photo.jpg&w=400&fm=webp" alt="Optimized photo" />
19
+
20
+ <!-- Cover crop to 200x200 square -->
21
+ <img src="/.netlify/images?url=/photo.jpg&w=200&h=200&fit=cover" alt="Cropped photo" />
22
+
23
+ <!-- Transform a remote image -->
24
+ <img src="/.netlify/images?url=https://example.com/image.jpg&w=800&q=80" alt="Remote image" />
25
+ ```
26
+
27
+ ## Query Parameters
28
+
29
+ | Parameter | Required | Type | Description |
30
+ |-----------|----------|------|-------------|
31
+ | `url` | Yes | `string` | Source image path (relative) or URL (remote, requires config) |
32
+ | `w` | No | `integer` | Width in pixels |
33
+ | `h` | No | `integer` | Height in pixels |
34
+ | `fit` | No | `string` | Resize mode: `contain` (default), `cover`, `fill` |
35
+ | `position` | No | `string` | Crop anchor for `fit=cover`: `center` (default), `top`, `bottom`, `left`, `right` |
36
+ | `fm` | No | `string` | Output format: `avif`, `jpg`, `png`, `webp`, `gif`, `blurhash` |
37
+ | `q` | No | `integer` | Quality 1-100 for lossy formats (default: 75) |
38
+
39
+ The `url` value must be URI-encoded when it contains special characters.
40
+
41
+ ## Fit Modes
42
+
43
+ | `fit=` | Aspect Ratio Maintained | Crops | Always Returns Exact Dimensions |
44
+ |--------|------------------------|-------|-------------------------------|
45
+ | `contain` (default) | Yes | No | No, one dimension may be smaller |
46
+ | `cover` | Yes | Yes | Yes, crops excess after proportional resize |
47
+ | `fill` | No | No | Yes, stretches/squishes to exact dimensions |
48
+
49
+ ### `fit=contain` (default)
50
+
51
+ Resizes proportionally to fit within the specified dimensions. If only one dimension is given, the other is calculated
52
+ to maintain aspect ratio.
53
+
54
+ ```html
55
+ <img src="/.netlify/images?url=/photo.jpg&w=600&h=400&fit=contain" />
56
+ ```
57
+
58
+ ### `fit=cover`
59
+
60
+ Resizes proportionally to fill the dimensions, then crops excess pixels. Requires **both** `w` and `h`. Use `position`
61
+ to control which area is retained.
62
+
63
+ ```html
64
+ <img src="/.netlify/images?url=/photo.jpg&w=300&h=300&fit=cover&position=top" />
65
+ ```
66
+
67
+ ### `fit=fill`
68
+
69
+ Stretches the image to exactly match the specified dimensions. May distort the image if aspect ratios differ.
70
+
71
+ ```html
72
+ <img src="/.netlify/images?url=/photo.jpg&w=400&h=200&fit=fill" />
73
+ ```
74
+
75
+ ## Format Negotiation
76
+
77
+ When `fm` is **not** specified, Image CDN automatically negotiates the best format using the browser's `Accept` header:
78
+
79
+ 1. Use `webp` if the browser accepts it
80
+ 2. Otherwise use `avif` if accepted
81
+ 3. Otherwise serve the original format
82
+
83
+ Explicitly set `fm` only when a specific format is required (e.g., `blurhash` for placeholders).
84
+
85
+ ## Remote Image Configuration
86
+
87
+ To transform images from external domains, allowlist them in `netlify.toml` using regex patterns:
88
+
89
+ ```toml
90
+ [images]
91
+ remote_images = [
92
+ "https://my-images\\.com/.*",
93
+ "https://animals\\.more-images\\.com/[bcr]at/.*"
94
+ ]
95
+ ```
96
+
97
+ Then reference the full URL:
98
+
99
+ ```html
100
+ <img src="/.netlify/images?url=https://my-images.com/photo.jpg&w=400" />
101
+ ```
102
+
103
+ Only absolute URLs to external servers need to be in `remote_images`. Local site images work without configuration.
104
+
105
+ ## Redirects & Rewrites
106
+
107
+ If you do not want to use the default `/.netlify/images` path, a redirect or rewrite can be used to have a different
108
+ URL. When doing so, the parameters can remain parameters to pass in or can be statically defined.
109
+
110
+ **Using `netlify.toml`:**
111
+
112
+ ```toml
113
+ [[redirects]]
114
+ from = "/transform-small/*"
115
+ to = "/.netlify/images?url=/:splat&w=50&h=50"
116
+ status = 200
117
+ ```
118
+
119
+ **Using `_redirects` file:**
120
+
121
+ ```
122
+ /transform-small/* /.netlify/images?url=/:splat&w=50&h=50 200
123
+ ```
124
+
125
+ **Usage:**
126
+
127
+ ```html
128
+ <!-- Transforms /photo.jpg with w=50&h=50 -->
129
+ <img src="/transform-small/photo.jpg" />
130
+ ```
131
+
132
+ DO NOT create circular redirects where an image URL redirects to another URL that redirects back. This causes infinite
133
+ loops and errors.
134
+
135
+ ## Custom Headers
136
+
137
+ Apply custom headers to source images on your site's domain. Headers propagate to the transformed output. ONLY do this
138
+ when explicitly asked.
139
+
140
+ **Using `netlify.toml`:**
141
+
142
+ ```toml
143
+ [[headers]]
144
+ for = "/source-images/*"
145
+ [headers.values]
146
+ Cache-Control = "public, max-age=604800, must-revalidate"
147
+ ```
148
+
149
+ **Using `_headers` file:**
150
+
151
+ ```
152
+ /source-images/*
153
+ Cache-Control: public, max-age=604800, must-revalidate
154
+ ```
155
+
156
+ **Limitations:**
157
+ - Custom headers only work for images on the same domain
158
+ - Cannot apply custom headers to remote source images
159
+ - Netlify respects cache headers that external domains send with their images
160
+ - `Cache-Control` headers on source images apply to browsers/CDNs, not the Netlify cache itself
161
+
162
+ ## Framework Integration
163
+
164
+ Many frameworks automatically use Netlify Image CDN when deployed to Netlify:
165
+
166
+ | Framework | Setup | Remote Image Allowlist |
167
+ |-----------|-------|----------------------|
168
+ | **Angular** | Automatic via `NgOptimizedImage` | `[images] remote_images` in `netlify.toml` |
169
+ | **Astro** | Automatic via `<Image />` component | `image.domains` or `image.remotePatterns` in `astro.config.mjs` |
170
+ | **Gatsby 5.13+** | Set env var `NETLIFY_IMAGE_CDN=true` | `[images] remote_images` in `netlify.toml` |
171
+ | **Next.js 13.5+** | Automatic with adapter v5 | `remotePatterns` in `next.config.js` |
172
+ | **Nuxt** | Automatic via `nuxt/image` module | `image.domains` in `nuxt.config.ts` |
173
+
174
+ ## Caching & Deploy Behavior
175
+
176
+ - Transformed images are uniquely cached at the edge per transformation parameters
177
+ - Future requests for the same transformation serve the cached version
178
+ - After a new deploy, cached images are invalidated if the source changed
179
+ - Source images are also cached to speed up future transformations
180
+ - Use asset fingerprinting (content hashes in filenames) for fine-grained cache control
181
+
182
+ ## Response Codes
183
+
184
+ | Condition | Response |
185
+ |-----------|----------|
186
+ | Valid query, new transformation | `200` with transformed image |
187
+ | Request for previously cached transformation | `304` Not Modified |
188
+ | Invalid parameter values or missing source | `404` Not Found |
189
+
190
+ ## Common Errors & Solutions
191
+
192
+ ### "404 on image transformation"
193
+
194
+ **Cause:** Invalid parameter values or source image not found.
195
+
196
+ **Fix:**
197
+
198
+ 1. Verify the source image exists at the specified `url` path
199
+ 2. Check parameter values are valid (e.g., `q` must be 1-100, `fit` must be `contain`, `cover`, or `fill`)
200
+ 3. For remote images, ensure the domain is in `remote_images` config
201
+
202
+ ### Blurry or low-quality output
203
+
204
+ **Cause:** Quality setting too low or dimensions too small.
205
+
206
+ **Fix:**
207
+
208
+ 1. Increase the `q` parameter (default is 75, max is 100)
209
+ 2. Ensure `w` and `h` are appropriate for the display size
210
+ 3. Use `fm=png` for images that need lossless quality
211
+
212
+ ### Remote image not loading
213
+
214
+ **Cause:** External domain not allowlisted.
215
+
216
+ **Fix:**
217
+
218
+ 1. Add the domain to `remote_images` in `netlify.toml`:
219
+ ```toml
220
+ [images]
221
+ remote_images = ["https://example\\.com/.*"]
222
+ ```
223
+ 2. Escape dots in regex patterns with double backslash
224
+ 3. Redeploy after updating config
225
+
226
+ ### Images not updating after deploy
227
+
228
+ **Cause:** Browser or CDN cache serving stale version.
229
+
230
+ **Fix:**
231
+
232
+ 1. Use asset fingerprinting (e.g., `/photo-abc123.jpg`) for cache busting
233
+ 2. Clear browser cache or use hard refresh
234
+ 3. Wait a few minutes for edge cache propagation
235
+
236
+ ### Circular redirect error
237
+
238
+ **Cause:** Redirect rule creates a loop with the image transformation endpoint.
239
+
240
+ **Fix:**
241
+
242
+ 1. Ensure redirect `from` path does not overlap with the `to` path
243
+ 2. Avoid redirecting `/.netlify/images` to another `/.netlify/images` URL
244
+ 3. Use status `200` (rewrite) not `301`/`302` (redirect) when possible
@@ -352,38 +352,6 @@ const response = await fetch(`${process.env.ANTHROPIC_BASE_URL}/v1/messages`, {
352
352
  })
353
353
  ```
354
354
 
355
- ## Local Development
356
-
357
- ### Netlify CLI
358
-
359
- Run `netlify dev` to start a local development server with AI Gateway env vars injected automatically.
360
-
361
- ```bash
362
- netlify dev
363
- ```
364
-
365
- ### Vite Plugin
366
-
367
- Alternatively, use the `@netlify/vite-plugin` for Vite-based projects:
368
-
369
- ```bash
370
- npm install @netlify/vite-plugin
371
- ```
372
-
373
- ```javascript
374
- // vite.config.js
375
- import { defineConfig } from 'vite'
376
- import netlify from '@netlify/vite-plugin'
377
-
378
- export default defineConfig({
379
- plugins: [netlify()],
380
- })
381
- ```
382
-
383
- Then run your normal dev command (`npm run dev`).
384
-
385
- **Requirement:** The site must have at least one production deploy before AI Gateway env vars become available locally.
386
-
387
355
  ## Available Models
388
356
 
389
357
  Key models per provider. For the latest list, see https://docs.netlify.com/build/ai-gateway/overview/.
@@ -473,7 +441,7 @@ token consumption is tracked per model and converted to Netlify credits.
473
441
  **Fix:**
474
442
 
475
443
  1. Ensure the site has at least one production deploy
476
- 2. Use `netlify dev` (not a bare `npm run dev`) for local development
444
+ 2. Deploy to Netlify
477
445
  3. Check that you are reading the env var in server-side code, not client-side browser code
478
446
 
479
447
  ### Rate limit exceeded (429)