@prismicio/vue - v2

Overview

@prismicio/vue is the official Prismic package for creating web apps with Prismic and Vue.js.

This version of the package targets Vue 2

To integrate Vue 3 with Prismic use the next version of this package, @prismicio/vue@next.

This package is formerly known as prismic-vue

@prismicio/vue used to be called prismic-vue. The latter is now deprecated and you can replace it with @prismicio/vue.

@prismicio/vue provides two main functionalities:

  • Plugin: It provides an @prismicio/client instance, preconfigures and exposes helpers from prismic-dom, and registers components globally.
  • Components: It provides a collection of components to render content from Prismic documents.

Dependencies and requirements

This package can only be used in a Vue project. It relies on @prismicio/client and prismic-dom as peer dependencies.

Since this is a general-purpose Vue.js library, it can be used in simple setups like Vue CLI or in more advanced frameworks that use Vue, like Nuxt, although we also offer a specific integration for the latter: @nuxtjs/prismic.

Installation

Install packages

Add @prismicio/vue and its peer dependencies to your Vue project via the command line:

  • npm
  • Yarn
npm
Copy
npm install @prismicio/vue@^2 @prismicio/client@^5 prismic-dom@^2
Yarn
Copy
yarn add @prismicio/vue@^2 @prismicio/client@^5 prismic-dom@^2

Create an optional Link Resolver

Create a Link Resolver function. This is one of the two ways to tell Vue how to handle internal links in Prismic documents. (The other way to do so is with a Route Resolver, which works better for more complex routes. Read a comparison.)

A Link Resolver function takes a document from Prismic as an argument and returns the URL path for that document. Here's a basic example of a linkResolver.js file.

Copy
export function linkResolver(document) {
  if (document.type === "post") {
    return "/blog/" + document.uid;
  }

  return "/";
}

Set up the plugin

The plugin allows settings for @prismicio/vue's Vue components, client, and helpers to be configured in one central location. This is done using Vue's plugin system.

Here's an example of setting up the plugin in your Vue setup file.

Copy
import Vue from "Vue";
import PrismicVue from "@prismicio/vue";
import App from "./App.vue";
import { linkResolver } from "./linkResolver";

Vue.use(PrismicVue, {
  endpoint: "your-endpoint",
  linkResolver,
});

new Vue({
  render: (h) => h(App)
}).$mount("#app");

Additional options for PrismicVue are described below.

Plugin usage

PrismicVue

Copy
import PrismicVue from "@prismicio/vue";

A Vue plugin to be used by the Vue application.

Copy
import Vue from "Vue";
import PrismicVue from "@prismicio/vue";
import App from "./App.vue";

Vue.use(PrismicVue, {
  endpoint: "your-endpoint",
});

new Vue({
  render: (h) => h(App)
}).$mount("#app");

PrismicVue accepts the following options. Only endpoint is mandatory:

endpoint

Required

A Prismic repository endpoint to init the plugin's @prismicio/client instance used to fetch content from a Prismic repository. Must be the full API endpoint (https://your-repo-name.cdn.prismic.io/api/v2).

apiOptions

An optional object used to configure the created @prismicio/client instance further. See the @prismicio/client documentation for configuration options.

linkResolver

An optional link resolver function used to resolve links to Prismic documents when not using the Route Resolver parameter with @prismicio/client.

htmlSerializer

An optional HTML serializer to customize the way Rich Text fields are rendered.

linkType

Internal link type to use, either "vueRouter" or "nuxt". Defaults to "vueRouter".

this.$prismic

By default, the plugin configures and injects in the Vue context:

  • An @prismicio/client instance at client, as well as predicate and cookie
  • asText, asHTML, asLink, asDate helpers from prismic-dom

All those properties and methods can be accessed through the Vue instance.

Copy
export default {
  mounted() {
    this.$prismic.client/* ... */);
    this.$prismic.asDate(/* ... */);

    // ...
  }
};

Components

The plugin also injects components into the app, so they can be used without imports. See below for more information.

Copy
<template>
  <PrismicRichText :field="document.data.myRichTextField" />
</template>

Components usage

@prismicio/vue provides a collection of components to render content from Prismic documents. All components described below are injected globally by the plugin. No imports are required if the plugin is configured.

<PrismicRichText>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const PrismicRichText = prismicVueComponents.common.RichText;

A Vue component that renders content from a Prismic Rich Text or Title field.

By default, HTML elements are rendered for each piece of content. For example, a heading1 block will render an <h1> HTML element. Internal links will use Vue Router, if available, for routing.

Copy
<PrismicRichText :field="document.data.myRichTextField" />

This component wraps its output in a <div> tag, if you need another wrapper tag, or component, to be used, use the wrapper prop.

Copy
<PrismicRichText :field="document.data.myRichTextField" wrapper="article" />

By default, if you're using the plugin, the component will use the link resolver and custom HTML serializer provided to it through the linkResolver and htmlSerializer options. In any case, you can still provide those explicitly to the component using the linkResolver and htmlSerializer props:

Copy
<PrismicRichText
  :field="document.data.myRichTextField"
  :link-resolver="linkResolver"
  :html-serializer="htmlSerializer"
/>

<PrismicText>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const PrismicText = prismicVueComponents.common.Text;

Vue component that renders content from a Prismic Rich Text or Title field as plain text.

Copy
<PrismicText :field="document.data.myTitleField" />

This component wraps its output in a <div> tag, if you need another wrapper tag, or component, to be used, use the wrapper prop.

Copy
<PrismicText :field="document.data.myTitleField" wrapper="h1" />

<PrismicLink>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const PrismicLink = prismicVueComponents.vueRouter.Link; // `.nuxt.Link` is also available

Vue component that renders a link from a Prismic Link field or a Prismic document.

This component automatically resolves a field's link to a URL. It also applies the correct target and rel props if Open in new tab is enabled for the field.

Copy
<PrismicLink :field="document.data.myLinkField">
  Click me
</PrismicLink>

The <RouterLink> component from Vue Router is used to render internal links, and an <a> HTML element is used for external links. With Nuxt, <NuxtLink> is used instead of <RouterLink>.

If your app uses Prismic's Route Resolver when querying for documents, providing a Link Resolver is optional.

If your app does not use the Route Resolver, or requires an override for specific URLs, the component will use the Link Resolver provided to the plugin through its linkResolver option if you're using it or through the component's linkResolver prop. The linkResolver component prop will take precedence over the linkResolver plugin option.

Copy
<PrismicLink
  :field="document.data.myLinkField"
  :linkResolver="linkResolver"
>
  Click me
</PrismicLink>

By default, if Open in new tab is enabled for the field, the component will render the rel attribute with a value of "noopener noreferrer".

This default can be overridden by using the blankTargetRelAttribute prop.

Copy
<PrismicLink
  :field="document.data.myLinkField"
  blank-target-rel-attribute="noopener"
>
  Click me
</PrismicLink>

The target and rel props allows your to set explicit value for those attributes.

Copy
<PrismicLink
  :field="document.data.myLinkField"
  target="_top"
  rel="noopener"
>
  Click me
</PrismicLink>

<PrismicImage>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const PrismicImage = prismicVueComponents.common.Image;

Vue component that renders content from a Prismic Image field.

Copy
<PrismicImage :field="document.data.myImageField" />

<PrismicEmbed>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const PrismicEmbed = prismicVueComponents.common.Embed;

Vue component that renders content from a Prismic Embed field.

Copy
<PrismicEmbed :field="document.data.myEmbedField" />

This component wraps its output in a <div> tag. To use another tag or component as the wrapper use the wrapper prop.

Copy
<PrismicEmbed :field="document.data.myEmbedField" wrapper="h1" />

This component's role is to render a Prismic Embed field safely. Because Prismic is not able to predict the nature of your embed output you must style it appropriately. For that purpose, you can target the data attributes generated by <PrismicEmbed> in your CSS.

Copy
/* Style text type embed */
[data-oembed-type="text"] {
  /* ... */
}

/* Style YouTube embed */
[data-oembed-provider="YouTube"] {
  /* ... */
}

/* Style embed from figma.com */
[data-oembed*="figma.com"] {
  /* ... */
}

<SliceZone>

Copy
// Not necessary when using the plugin
import prismicVueComponents from "@prismicio/vue/components";

const SliceZone = prismicVueComponents.common.SliceZone;

Vue component that renders content from a Prismic Slice Zone using Vue components for each type of Slice.

For example, if a Slice Zone contains a Text Slice followed by an Images Slice, <SliceZone> will render <TextSlice> and <ImagesSlice> in a list.

Copy
<SliceZone
  :slices="document.data.body"
  :components="{
    text: TextSlice,
    images: ImagesSlice,
  }"
/>

Alongside the slices prop, an object of Slice type IDs (for example: "text") mapped to its Vue component (for example: <TextSlice>) should be provided to the components prop. Components can be supplied in a variety of ways.

Copy
import FooSlice from "~/slices/FooSlice";

const components = {
  // Explicit import
  foo: FooSlice,

  // Assuming "BarSlice" is registered globally in your Vue application
  bar: "BarSlice",

  // Async components are also a great way to achieve code splitting
  baz: () => import("~/slices/BazSlice.vue"),
};

Slice components receive four props:

  • slice: The Slice object being rendered.
  • index: The index of the Slice within the Slice Zone.
  • slices: The list of all Slices objects in the Slice Zone.
  • context: Arbitrary data passed to the <SliceZone>'s context prop.

Because defining props in Vue.js is verbose, we provide a helper function to do so: getSliceComponentProps(). With it, a simple Slice component could look like this.

Copy
<template>
  <PrismicRichText :field="slice.primary.text" />
</template>

<!-- Options API -->
<script>
import { getSliceComponentProps } from "@prismicio/vue/components";

export default {
  // The array passed to `getSliceComponentProps` is purely optional and acts as a visual hint for you
  props: getSliceComponentProps(["slice", "index", "slices", "context"])
}
</script>

If you have data that needs to be shared with all Slice components, provide a value to the context prop of the <SliceZone> component. The value will be passed to each Slice component as a context prop.

Copy
<SliceZone
  :slices="document.data.body"
  :components="{
    text: TextSlice,
    images: ImagesSlice,
  }"
  :context="{ foo: 'bar' }"
/>

By default, a "TODO" component will be rendered with a warning if a component is not provided for a Slice type.

This default can be overridden by using the defaultComponent prop. The default component is passed the same props listed above.

Copy
<SliceZone
  :slices="document.data.body"
  :default-component="null"
/>

The default "TODO" component will not be rendered in production (i.e. when process.env.NODE_ENV is production).

The <SliceZone> component wraps its output in a <div> tag, if you need another wrapper tag, or component, to be used, you can use the wrapper prop.

Copy
<SliceZone
  :slices="document.data.body"
  :components="{
    text: TextSlice,
    images: ImagesSlice,
  }"
  wrapper="article"
/>

Upgrading from vue-slicezone

<SliceZone> from @prismicio/vue replaces the component from the vue-slicezone package. If you are currently using vue-slicezone with a resolver prop, you can still pass that prop to the updated component.

<SliceZone
  :slices="document.data.body"
  :resolver="({ sliceName }) => {
    switch (sliceName) {
      case 'text':
        return TextSlice;

      case 'images':
        return ImagesSlice;
    }
  }"
/>

The resolver prop is deprecated and will be removed in a future major release. Please upgrade to the simpler components prop using the object format described above.


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.