Inline audio player in Sanity.io rich text
How to use the Portable Text Editor's flexibility to insert audio file, host on Sanity and render it with Nextjs!!
Starting with the schema, we need to add the inlineAudio
schema type to our block content's of
property
import { defineType, defineArrayMember } from "sanity";
export default ({
name: "blockContent",
title: "Block Content",
type: "array",
of: [
defineArrayMember({
name: "inlineAudio",
title: "Inline audio player",
type: "file",
options: {
accept: "audio/*",
},
}),
],
});
Now editors have the ability to add inline audio players to their content! Let's cover how to render this in the front-end.
1. Install @portabletext/react
npm install @portabletext/react
// page.tsx
import { client } from "../../lib/sanity.client"
import { postQuery } from "../../lib/sanity.queries"
import { PortableText } from "@portabletext/react";
type Props = {
params: {
slug: string;
};
};
export default async function Post({ params: { slug } }: Props) {
const post: Post = await client.fetch(postQuery, { slug });
return (
<div>
<PortableText value={post.body} components={RichTextComponents} />
</div>
)
}
2. Customising components
// RichTextComponents.tsx
export const RichTextComponents = {
types: {
inlineAudio: ({ value }: any) => {
const ref = value.asset._ref;
const projeccId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET;
const [_file, id, extension] = ref.split("-");
const audioUrl = `https://cdn.sanity.io/files/${projeccId}/${dataset}/${id}.${extension}`;
return (
<audio controls>
<source src={audioUrl} type="audio/mpeg" />
</audio>
);
},
},
}
And that's it! There are many more interesting use cases, some of which I hope to cover in the future.
Reference:
https://github.com/portabletext/react-portabletext