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

easy-prismic-react

v1.1.0

Published

Render and fetch prismic data with ease

Downloads

3

Readme

Lines npm npm github release github issues github closed issues

easy-prismic-react

A better way of using Primsic with react. This package doubles as an HTML serializer and an API wrapper. Modern, tested and fully written in typescript.

Based on prismic-reactjs and written here at easyblue.io, a french insurtech company. Check out our website to see how we're using prismic and this package in production.

Installation

yarn install easy-prismic-react or npm install easy-prismic-react

Basic Usage

HTML Serializer

import { PrismicHTMLSerializer, PrismicDocument } from 'easy-prismic-react';

export function linkResolver(doc: PrismicDocument<any>): string {
  switch (doc.type) {
    case 'some_content_type':
      return `/your/route/${doc.uid}`;
    default:
      return '/';
  }
}

const easyPrismicReact = new PrismicHTMLSerializer({ linkResolver });

function MyComponent () {
    return easyPrismicReact.renderRichText(this.props.someRichText);
}

API Wrapper

import { PrismicAPIWrapper, PrismicDocument, PrismicElement } from 'easy-prismic-react';

// The following type lists your prismic custom types ids.
type TContentTypes = 'blog_post' | 'product_page' | 'faq_page';
// You should use an interface for each custom type, this will allow you to have a better type definition throughout your code.
interface BlogPost {
    title: string;
    content: PrismicElement[];
}

// Instantiate the API wrapper with your prismic endpoint
const apiWrapper = new PrismicAPIWrapper<TContentTypes>({ endpoint: 'https://your-prismic-repo.cdn.prismic.io/api/v2' });

// Simple function that fetches blog posts by only returning content with the `blog_post` type
// If you're fetching data from the server side, use a req-like object from express or next for instance.
// If you're fetching from the client side, just use null instead.
export async function getBlogPost(reqLikeObject: IncomingMessage): Promise<PrismicDocument<BlogPost>> {
  return apiWrapper.getContent<BlogPost>(
    reqLikeObject,
    apiWrapper.getContentByType('blog_post')
  );
}

Custom serializers

Although the serializer takes care of turning your WYSIWYG content into proper HTML, you might need to customize how your content is rendered.

The most common use case is the hyperlink serializer. By default, this package will render a plain <a> tag. You might want to replace that with your own router like react-router or next's router.

In order to set up your own serializers, you need to pass a object when instantiating PrismicHTMLSerializer like so :

const apiWrapper = new PrismicAPIWrapper({
    endpoint: 'https://your-prismic-repo.cdn.prismic.io/api/v2',
    customSerializers: {
        'hyperlink': (params: SerializeParams) => {
            return (
                 <MyNavigationComponent />
            );
        }
    }
});

Your function will receive a params argument with everything you might need in order to tweak your rendering. Take a look at the SerializeParams interface.

💡 You can override all tags that are handled by the serializer, check the ElementTypes enum for the complete list.

The getURL method

If you need to transform a prismic link (PrismicLink) object into a string, you can use the getURL(prismicLink: PrismicLink): string method once your serializer is instantiated.

Full API


class PrismicHTMLSerializer {
    public static serializers; // Default serializers you might want to use yourself

    constructor(params: SerializerSetupParams);

    public renderRichText(richText: PrismicElement[], Component: any = Fragment, componentProps = {}, options: SerializeOptions = {}, context?: any): ReactElement;
    public getURL(prismicLink: PrismicLink): string;
}

class PrismicAPIWrapper<TContentTypes> {
    constructor(params: WrapperSetupParams);
    
    public async initAPI(req: any): Promise<ResolvedApi>;
    public async getContent<T>(req: any, query: string[], queryOptions: QueryOptions = {}): Promise<SearchResponse<T>>;
    public getContentByType(type: TContentTypes): string[];
    public getContentByUID(page: TContentTypes, uid: string): string[];
    // TODO : every stripe API parameter needs to have a dedicated method
}

Advanced usage : custom embeds and the context param

Prismic is a double edged sword : it's very lightweight and easy to pick up, but it might lack some features if you need to render more complicated content inside the WYSIWYG editor. easy-prismic-react lets you get started quickly, while also giving you leeway in order to implement advanced features.

For our blog, we wanted to display banners with internal links in the middle of articles. Setting up a banner needs to be easy for contributors whilst letting them customizing their content. Here's how it turned out :

Prismic custom embed easy-prismic-react easyblue

The first step is to customize the <pre> renderer in order to parse these "shortcodes" of some kind.

const easyPrismicReact = new PrismicHTMLSerializer({
  linkResolver,
  customSerializers: {
    ['preformatted']: (params: SerializeParams) => {
      const { index, context } = params; // Note how we get the context here
      // Some logic here in order to find out which embed is being used (or none at all)...
      switch (embed) {
        case RELATED_POST_SHORT_CODE:
          return (<RelatedPostEmbed key={`embed-${index}`} postContext={context}/>);
        // More cases...
        default:
        // This doesn't look like a short code, use the default serializer that's available as a static method
          return PrismicHTMLSerializer.serializers.serializeStandardTag('pre', element, children, index);
      }
    }
  }
});

The second step is to pass a context when calling the serializer. This will let us pass any data that we will get back in our params argument, inside the custom serializer.

In our blog post component :

function BLogPost () {
    const blogPostContext = {}; // Fetch related posts data here
    return (
        <div>
            { easyPrismicReact.renderRichText(content, Fragment, {}, {}, blogPostContext) }
        </div>
    );
}

Thanks to this feature, we can access our related posts data that we fetched earlier, and render a proper link, like so :

const RelatedPostEmbed = ({ postContext }) => {
  // Extract the related post data from the context we passed a react prop earlier 
  const relatedPost = getRelatedPost(postContext);
  const { data } = relatedPost;

  // Render our custom router component leading to the related post
  return (
    <YourCustomRouter href={...}>
        <PostImage image={data.image.url} />
          Related post
          <h4>{data?.title}</h4>
    </YourCustomRouter>
  );
};