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 🙏

© 2020 – Pkg Stats / Ryan Hefner

@stnew/prismic-react

v1.1.0

Published

Prismic components and utilities for React

Downloads

76

Readme

@stnew/prismic-react

@stnew/prismic-react has peerDepenendencies of react and react-dom. This package assumes you have a basic React app running and have set up the Prismic client.

This package exports:

PrismicContext

For the most part, you'll want to use the usePrismic hook to access context. If not, it's exported from the package main:

import { PrismicContext } from '@stnew/prismic-react'

function Consumer() {
  return (
    <PrismicContext.Consumer>
      {value => /* render something based on the context value */}
    </PrismicContext.Consumer>
  )
}

PrismicProvider

In order for @stnew/prismic components to work, you'll need to wrap your App in PrismicProvider and pass a few props.

// _app.js
import { PrismicProvider } from '@stnew/prismic'
import { sliceMap } from 'slices'
import { linkResolver, hrefResolver } from 'lib/prismic'
import { elementsMap } from 'components/TextField'

function App({ Component, pageProps }) {
  return (
    <PrismicProvider
      slices={sliceMap}
      linkResolver={linkResolver}
      hrefResolver={hrefResolver}
      htmlSerializer={elementsMap}
    >
      <Component {...pageProps}>
    </PrismicProvider>
  )
}
PropRequiredType
slicesYes{ [key: string]: (props: any) => Element }
linkResolverYes(doc?: PrismicDoc) => string
hrefResolverNo(doc?: PrismicDoc) => string
htmlSerializerNo{ [Element]: [React.ReactNode, { ...props }]

Pass the sliceMap, linkResolver, and hrefResolver to their respective props. See the HTML Serializer section to learn more it's usage.

SliceZone

The SliceZone component will render slices from Prismic.

When you query Prismic's REST API, you'll get back a data object that contains all the fields you set up for that content type. The body property is a reserved key in Prismic, and it will contain all of your slices. Pass this to the data prop in SliceZone.

// pages/index.js
import { SliceZone } from '@stnew/prismic-react'
import { prismicClient } from 'lib/prismic'

function Page({ data }) {
  return (
    <main>
      <h1>{data.title}</h1>
      <SliceZone data={data.body} />
    </main>
  )
}

export async function getStaticProps() {
  const document = await prismicClient.getByUID('page', 'homepage')
  const { data } = document

  return {
    props: {
      data
    }
  }
}

sliceMap

Each Slice in data.body is an object with all of the slice data.

{
  "primary": {},
  "items": [],
  "slice_label": null,
  "slice_type": "slice_name"
}

In order for slices to be available to SliceZone, you'll need to setup a map of all your slices. The key is the slice_type, the value is your React component.

// slices/index.js
import { CoolSlice } from './CoolSlice'
import { GoodSlice } from './GoodSlice'

/**
 * @key slice_type
 * @value React Component
 */
export const sliceMap = {
  'cool_slice': CoolSlice,
  'good_slice': GoodSlice,
}

This map can be passed to <PrismicProvider>'s slices prop to make it available to all, or at the page level by passing it to <SliceZone>'s slices prop. If you have both, it will combine them, so you can have some slices that are global and some slices specific to each page. This helps diminish bundle size.

// Pass to PrismicProvider...
function App() {
  return (
    <PrismicProvider slices={sliceMap}>
      {...}
    </PrismicProvider>
}

// ... or pass to SliceZone...
function Page() {
  return <SliceZone data={data.body} slices={sliceMap}>
}

SliceZone will pass all of the slice data to each component as props.

function CoolSlice({ primary, items }) {

  const { title, sub_title } = primary

  return (
    <div>
      <h1>{title}</h1>
      <h2>{sub_title}</h2>
      {items.map((item, i) => (
        <p key={i}>{item.copy}</p>
      ))}
    </div>
  )
}

Code-Splitting

If your app has a ton of slices, including them on every single page can cause bloat. SliceZone lets you dynamically import components for smaller bundles.

// slices/index.js
const CoolSlice = import('./CoolSlice')
const GoodSlice = import('./GoodSlice')

export const sliceMap = {
  'cool_slice': CoolSlice,
  'good_slice': GoodSlice,
}

This also works with next/dynamic imports.

usePrismic

All of this magic is thanks to the usePrismic hook. You probably won't need this, but the hook will return everything from PrismicContext.

import { usePrismic } from '@stnew/prismic-react'

function Component() {
  const {
    sliceMap,
    linkResolver,
    hrefResolver,
    htmlSerializer,
  } = usePrismic()

  return <SliceZone slices={sliceMap} />
}

HTML Serializer

Using the serializer requires that you've installed prismic-reactjs. If you haven't, install with

npm install prismic-reactjs

Prismic's RichText field returns structured data that needs to be parsed to render as HTML. Wwile you could write your own parser, we recommend using the RichText component to render it instead.

import { RichText } from 'prsimic-reactjs'

function Page({ data }) {
  return (
    <main>
      <h1>{data.title}</h1>
      <RichText render={data.body_copy} />
    </main>
  )
}

The default RichText component will render pretty generic HTML. If you need to use special text components, add classNames and props, or render custom HTML, you'll need to write and HTML Serializer

Mapping the elements

The serializer accepts a special mapping

import { Elements } from 'prsimic-reactjs'
import Link from 'next/link'

const elementsMap = {
  [Elements.heading1]: ['h1', { className: 'heading-1' }],
  [Elements.heading2]: ['h2', { className: 'heading-2' }],
  [Elements.paragraph]: ['p', { className: 'paragraph' }],

  [Elements.hyperlink]: [Link, ({ data }) => { href: data.url }]
  [Elements.hyperlink]: ['img', ({ data }) => { href: data.src }]
}

You can then pass this map the the htmlSerializer prop

function App() {
  return (
    <PrismicProvider
      htmlSerializer={elementsMap}
      linkResolver={linkResolver}
    >
      {...app}
    </PrismicProvider>
  )
}

The serializer will be returned by the usePrismic hook.

import { RichText } from 'prsimic-reactjs'

function TextField({ render }) {
  const { htmlSerializer, linkResolver } = usePrismic()
  return <RichText
    render={render}
    htmlSerializer={htmlSerializer}
    linkResolver={linkResolver}
  />
}

useHtmlSerializer

If you only need to use the HTML serializer in one component, it might make sense to use it as a hook

import { RichText } from 'prsimic-reactjs'
import { elementsMap } from 'lib/prismic/serializer'
import { useHtmlSerializer } from '@stnew/prismic-react'

function TextField({ render }) {
  const htmlSerializer = useHtmlSerializer(elementMap)

  return <RichText
    render={render}
    htmlSerializer={htmlSerializer}
    linkResolver={linkResolver}
  />
}

htmlSerializerThunk

Besides a hook or provider, you can export the wrapper function that creates the serializer function.

import { elementsMap } from 'lib/prismic/serializer'
import { useHtmlSerializer } from '@stnew/prismic-react'

const htmlSerializer = htmlSerializerThunk(elementMap)