👀 Our most exciting product launch yet 🚀 Join us May 8th for Sanity Connect

Troubleshooting a custom Twitter embed for block inputs in Sanity.io

3 replies
Last updated: Mar 23, 2023
I’m trying to follow a guide to build a custom twitter embed for block inputs. It currently just gives me an error “*Error: Cannot destructure property ‘id’ of ‘value’ as it is undefined.”* Any advice on where I’ve gone wrong? It feels like once I can get one to work, it should be easy to build out others.

import { defineType } from "sanity";
import React from 'react'
import { TwitterTweetEmbed } from 'react-twitter-embed'

const TwitterPreview = ({ value }) => {
    const { id } = value;
    if (!id) {
        return <p>Missing id for Twitter post</p>;
    }

    return (<TwitterTweetEmbed tweetId={id} options={{ conversation: 'none' }} />);
}

export default defineType({
    name: 'twitter',
    type: 'object',
    title: 'Twitter',
    fields: [
        {
            name: 'id',
            type: 'string',
            title: 'Twitter tweet id',
            validation: (Rule) => Rule.required()
        },
    ],
    preview: {
        select: {
            id: 'id'
        },
        prepare(selection) {
            const { id } = selection;

            return {
                id: 'id'
            };
        }
    },
    components: {
        preview: TwitterPreview,
    }
});
Mar 23, 2023, 1:26 PM
👋 Hey User!
Here are the conceptual docs on the v3 preview component for reference:
https://www.sanity.io/docs/form-components#0319196f086b And the reference docs:
https://www.sanity.io/docs/form-components-reference#79eebe95aac7
Now, my usual next debugging step here would be to just log the whole props passed to
TwitterPreview
, as
value
is not defined.
I added your schema to my project and noticed two things:

1. In your return from prepare, you are returning
id: 'id'
- that is, you’re returning the string “id” as the value for the property
id
. You would want to return
id: id
to use the value. But you don’t actually need
prepare
in this case,
select
is enough to grab the ID and pass it to the component.2. The values are just passed as regular props, so your component could be written as
const TwitterPreview = ({ id })
So I would do two things -
1. Remove the prepare statement
2. Update the component to grab
id
from the top-level propsAnd let us know how that goes!
Mar 23, 2023, 3:18 PM
woot i got it working
Mar 23, 2023, 3:27 PM
import { defineField, defineType } from "sanity";
import React from 'react'
import { TwitterTweetEmbed } from 'react-twitter-embed'

const TwitterPreview = ({ id }) => {
    console.log(id);
    if (!id) {
        return <p>Missing id for Twitter post</p>;
    }

    return (<TwitterTweetEmbed tweetId={id} options={{ conversation: 'none' }} />);
}

export default defineType({
    name: 'twitter',
    type: 'object',
    title: 'Twitter',
    fields: [
        defineField({
            name: 'id',
            type: 'string',
            title: 'Twitter tweet id',
            validation: (Rule) => Rule.required()
        }),
    ],
    preview: {
        select: {
            id: 'id'
        }
    },
    components: {
        preview: TwitterPreview,
    }
});
Mar 23, 2023, 3:28 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?