npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

payload-lexical-nuxt-serializer

v1.0.3

Published

Nuxt module to serialize Payload lexical nodes

Downloads

5

Readme

Payload Lexical Nuxt Serializer

npm version

npm downloads

License

Nuxt

A Nuxt module that provides components for rendering rich text nodes and block fields from PayloadCMS's Lexical Editor. This module simplifies the process of displaying complex content structures in your Nuxt application.

Features

  • <BlockRenderer /> component - Render Block fields from you're collections
  • <RenderContent /> component - to render specific lexical node objects

Note

This module is still kind of experimental and may have some bugs. If you find any issues, please report them or feel free to contribute. Also, I'm basically just building this for my own projects, so if you have any feature requests, feel free to open an issue or PR as well.

Setup

Install the module to your Nuxt application with one command:

pnpm dlx nuxi module add payload-lexical-nuxt-serializer

Add the componentsMap object to your Nuxt app's configuration in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  components: true,
  payloadLexicalNuxtSerializer: {
    componentsMap: {
      hero: 'BlockHero',
    },
  },
})

BlockRenderer Component

The BlockRenderer component is a simple component that allows you to render block fields from your collections dynamically. It uses the useRuntimeConfig hook from Nuxt to access the componentsMap object. This object maps block types to Vue component names. When rendering, the BlockRenderer component iterates over each block in the blocks array. For each block, it uses the blockType property to look up the corresponding Vue component in the componentsMap. If a matching component is found, it's dynamically imported and rendered with the block data.

Usage

The BlockRenderer component takes an array of blocks as a prop. Each block in the array should be an object that includes a blockType property. The blockType property is used to determine which Vue component should be used to render the block.


<script setup lang="ts">
  const { data } = await useFetch(`/api/page?slug=someSlug`)
</script>
<template>
  <BlockRenderer :blocks="data?.blocks"/>
</template>

RenderContent Component

The RenderContent component is a utility component that allows you to render specific lexical node objects. It's designed to work with the rich text nodes from PayloadCMS's Lexical Editor, providing a seamless way to display complex content structures. It is very convenient to use when creating custom Block components.

Usage

The RenderContent component takes a content prop which should be an object representing the lexical node to be rendered. Optionally, it can also take a classConfig prop which is an array of classes to be applied to the rendered content. It uses the $serialize method from the Nuxt app to serialize the lexical node into HTML. The classConfig prop is passed to the $serialize method to apply the specified classes to the rendered content.


<script setup>
  const { data } = await useFetch(`/api/page?slug=someSlug`)

  const classConfig = [
    { tag: 'h3', class: 'font-bold' }
  ]
</script>

<template>
  <RenderContent :content="data?.content" :classConfig="classConfig"/>
</template>

This approach allows you to render any lexical node with custom classes, providing flexibility in how your content is displayed.

Examples

Rendering a blocks field from a Payload Collection

Suppose you have a collection with a block field called content. The content field is an array of blocks, each with a blockType property that specifies the type of block. You can use the BlockRenderer component to render the blocks dynamically.


<script lang="ts" setup>
  import type { Page } from '~/types/payload'

  const { data: homePage, error } = await useFetch<Page>('/api/page?slug=index&depth=3')
</script>
<template>
  <div>
    <BlockRenderer v-if="homePage?.content" :blocks="homePage.content"/>

    <div v-else>
      <template v-if="!homePage && !error">
        <h1>Nothing to render yet.</h1>
      </template>

      <template v-else-if="error">
        <ErrorComponent :error="error"/>
      </template>
    </div>
  </div>
</template>

Creating Block Components

To create custom block components, you can leverage the RenderContent component to render specific lexical node objects within your block component.


<script setup lang="ts">
  import type { Hero } from '~/types/payload'

  const props = defineProps<{
    block: Hero
  }>()
</script>

<template>
  <section>
    <div>
      <RenderContent
        :content="block.heading"
        :class-config="[
          { tag: 'h1', class: 'font-extrabold' },
        ]"
      />
    </div>

    <div>
      <RenderContent
        :content="block.subheading"
      />
    </div>
  </section>
</template>

In this example, the RenderContent component is used twice:

  1. To render the heading content of the block with custom classes applied to the h1 tag.
  2. To render the subheading content of the block without any custom classes.

The classConfig prop is used to specify the tag and classes to be applied to the rendered content. This allows you to customize the styling and markup of the rendered content within your block component.

Remember to register your block components in the componentsMap object in your Nuxt app. This object maps block types to Vue component names, allowing the BlockRenderer component to dynamically import and render the correct component for each block.

// nuxt.config.ts
export default defineNuxtConfig({
  components: true,
  payloadLexicalNuxtSerializer: {
    componentsMap: {
      hero: 'BlockHero',
    },
  },
})