Thinkmill / Thinkmill/keystatic

Trying to preview a componentBlock image in the editor

Open
#1,420 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.4k
Forks
159
Avg merge
21h 41m
Merged PRs (30d)
2

Description

Hey, Im having a hard time figuring this one out!

I'm using Astro. I've created two component blocks that I want to use in blog posts: Youtube Videos, and images. I've been able to preview the youtube videos in my editor without issue, with the help of this video.

But for the life of me, I don't know how to render a preview of the image as well. I've changed my config file from TS to TSX, imported React, etc... and I just can't get a dang image to preview.

Digging through the KeyStatic Docs, I think this organization principle might be relevant...

Regardless of where the posts entries are created, the coverImage image will be generated in public/images/posts/{post-slug}.

My best guess is that, since images must be generated within the same folder as a post (I hope I'm wrong here -- am i?), then there's no way to preview the images since there's no way to dynamically generate the path to the image.

Please tell me I'm wrong. There simply must be a way to preview images within the document editor!

Here's the relevant code (keystatic.config.tsx)

// keystatic.config.tsx

import { config, fields, collection, component } from '@keystatic/core'
import React from 'react'

export default config({
	storage: {
		kind: 'local',
	},
	collections: {
		posts: collection({
			label: 'Posts',
			slugField: 'title',
			path: 'src/content/posts/*/',
			format: { contentField: 'content' },
			schema: {
				title: fields.slug({ name: { label: 'Title' } }),
				content: fields.document({
					label: 'Content',
					formatting: true,
					links: true,
					componentBlocks: {
						youtubeVideo: component({
							label: 'YouTube Video',
							preview: ({ fields }) => (
								<div style={{ padding: '1rem', backgroundColor: '#f9f9f9' }}>
									{fields.youtubeVideoId.value ? (
										<iframe
											width='100%'
											height='315'
											src={`https://www.youtube.com/embed/${fields.youtubeVideoId.value}`}
											frameBorder='0'
											allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'
											allowFullScreen
										></iframe>
									) : (
										<p>Please enter a YouTube video ID</p>
									)}
									<h3>{fields.videoTitle.value}</h3>
									<p>{fields.videoDescription.value}</p>
								</div>
							),
							schema: {
								youtubeVideoId: fields.text({ label: 'YouTube Video ID' }),
								videoTitle: fields.text({ label: 'Video Title' }),
								videoDescription: fields.text({ label: 'Video Description' }),
							},
						}),
						astroImage: component({
							label: 'Astro Image',
							preview: ({ fields }) => {
								const image = fields.imageSrc.value
								const imageUrl = image
									? `content/posts/{post.name}/content/${image.filename}`
									: ''
								return imageUrl ? (
									<img
										src={imageUrl}
										alt={fields.imageAlt.value || 'Astro Image'}
										title={fields.imageTitle.value}
										style={{ maxWidth: '100%', height: 'auto' }}
									/>
								) : (
									<p>Please select an image</p>
								)
							},
							schema: {
								imageSrc: fields.image({
									label: 'Image Source',
									directory: 'src/content/posts/*/content',
								}),
								imageTitle: fields.text({ label: 'Image Title' }),
								imageAlt: fields.text({ label: 'Alt Text' }),
							},
						}),
					},
				}),
			},
		}),
	},
})

I would appreciate any help very much, I simply must be wrong that this is not possible!

Thank you very much.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in keystatic.config.tsx at the astroImage component preview and its fields.imageSrc configuration. Trace how the selected image value and its filename are exposed to the preview, then verify the generated path against the collection path. Done means a selected image renders in the document editor preview, with the empty-state message still appearing when no image is selected.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
content, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.