Inline audio player in Sanity.io rich text

Cover Image for 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

Blog Post Image

More Stories