Skip to content

Commit

Permalink
Merge pull request #188 from bluecadet/fix/sanity
Browse files Browse the repository at this point in the history
add sanity fixes
  • Loading branch information
claytercek authored Nov 26, 2024
2 parents b0fc20b + aa37868 commit 2ed13d2
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/olive-tomatoes-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bluecadet/launchpad-content": minor
---

Update mediaDownloader and sanityImageUrlTransform defaults
1 change: 1 addition & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export default defineConfig({
{ text: "Custom Content Source", link: "/recipes/custom-content-source" },
{ text: "Custom Content Plugin", link: "/recipes/custom-content-plugin" },
{ text: "Custom Monitor Plugin", link: "/recipes/custom-monitor-plugin" },
{ text: "Transforming Sanity Images", link: "/recipes/transforming-sanity-images" },
],
},
{
Expand Down
119 changes: 119 additions & 0 deletions docs/src/recipes/transforming-sanity-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Transforming Sanity Images

When working with Sanity.io images, you can leverage Sanity's built-in image transformation capabilities instead of using the `sharp` plugin. This is particularly useful for handling Sanity's hotspot and crop features.

## Fetching Images with GROQ

First, ensure your GROQ query includes all necessary image fields:

```typescript{12-17}
import { defineConfig } from '@bluecadet/launchpad-core';
import { sanitySource } from '@bluecadet/launchpad-content';
export default defineConfig({
content: {
sources: [
sanitySource({
id: 'content',
projectId: 'your-project-id',
queries: [{
id: 'pages',
query: `*[_type == "page"]{
image {
...,
asset->
}
}`
}]
})
],
plugins: [
mediaDownloader()
]
}
});
```

The `asset->` reference is crucial for accessing the full image data, including hotspot and crop information.

## Using the Image URL Transform Plugin

Add the `sanityImageUrlTransform` plugin to transform image references into URLs:

```typescript{14-22}
import { defineConfig } from '@bluecadet/launchpad-core';
import { sanityImageUrlTransform, sanitySource } from '@bluecadet/launchpad-content';
export default defineConfig({
content: {
sources: [
sanitySource({
id: 'content',
projectId: 'your-project-id',
queries: [/* ... */]
})
],
plugins: [
sanityImageUrlTransform({
projectId: 'your-project-id',
dataset: 'production',
buildUrl: (builder) => builder
.width(800)
.format('webp')
.fit('crop')
.crop('center')
}),
mediaDownloader()
]
}
});
```

>[!TIP]
>It's added _before_ the mediaDownloader (unlike the `sharp` plugin) because it modifies
## Available Transformations

Sanity's image URL builder supports many transformations:

```typescript
import { defineConfig } from '@bluecadet/launchpad-core';
import { sanityImageUrlTransform, sanitySource } from '@bluecadet/launchpad-content';

export default defineConfig({
content: {
sources: [
sanitySource({
id: 'content',
projectId: 'your-project-id',
queries: [/* ... */]
})
],
plugins: [
sanityImageUrlTransform({
projectId: 'your-project-id',
dataset: 'production',
buildUrl: (builder) => builder
.width(800) // Set width
.height(600) // Set height
.format('webp') // Convert format
.quality(80) // Adjust quality
.auto('format') // Auto-select best format
.fit('crop') // Crop fitting
.crop('center') // Crop position
.blur(10) // Apply blur
}),
mediaDownloader()
]
}
});
```

## Resources

- [Sanity Image URLs Reference](https://www.sanity.io/docs/image-url)
- [Image Image Presentation Documentation](https://www.sanity.io/docs/presenting-images)
- [sanityImageUrlTransform Plugin](../reference/content/plugins/sanity-image-url-transform.md)
- [Sanity Content Source](../reference/content/sources/sanity-source.md)

Unlike the `sharp` plugin, Sanity's image transformations are performed on their CDN, reducing your build time and server load.
2 changes: 1 addition & 1 deletion docs/src/reference/content/plugins/media-downloader.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Specifies which data keys to search for media URLs. If not provided, all keys wi
### `mediaPattern`

- **Type:** `RegExp`
- **Default:** `/\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i`
- **Default:** `/https?.*\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i`

Regex pattern to match URLs for downloading.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ JSONPath to the content to transform. By default, matches all nodes with `_type`
### `buildUrl`

- **Type:** `(builder: ImageUrlBuilder) => ImageUrlBuilder`
- **Required**
- **Default:** `builder => builder`

Function to configure image transformations using Sanity's image URL builder.

Expand Down
2 changes: 1 addition & 1 deletion packages/content/src/plugins/media-downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import ResultAsyncQueue from "../utils/result-async-queue.js";
import { safeKy } from "../utils/safe-ky.js";
import { CacheProgressLogger, parsePluginConfig, queryOrUpdate } from "./contentPluginHelpers.js";

const DEFAULT_MEDIA_PATTERN = /\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i;
const DEFAULT_MEDIA_PATTERN = /https?.*\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i;

declare module "../content-plugin-driver.js" {
interface ContentHookArgs {
Expand Down
1 change: 1 addition & 0 deletions packages/content/src/plugins/sanity-image-url-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const sanityImageUrlTransformSchema = z.object({
buildUrl: z
.function(z.tuple([z.custom<ImageUrlBuilder>()]))
.returns(z.custom<ImageUrlBuilder>())
.default((bldr) => bldr)
.describe("Function to build the image URL"),
});

Expand Down

0 comments on commit 2ed13d2

Please sign in to comment.