@prismicio/vue - v2
Overview
@prismicio/vue
is the official Prismic package for creating web apps with Prismic and Vue.js.
@prismicio/vue
provides two main functionalities:
- Plugin: It provides an
@prismicio/client
instance, preconfigures and exposes helpers fromprismic-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 install @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.
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.
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
import PrismicVue from "@prismicio/vue";
A Vue plugin to be used by the Vue application.
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 resolves 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 atclient
, as well aspredicate
andcookie
asText
,asHTML
,asLink
,asDate
helpers fromprismic-dom
All those properties and methods can be accessed through the Vue instance.
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.
<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>
// 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.
<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.
<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:
<PrismicRichText
:field="document.data.myRichTextField"
:link-resolver="linkResolver"
:html-serializer="htmlSerializer"
/>
<PrismicText>
// 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.
<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.
<PrismicText :field="document.data.myTitleField" wrapper="h1" />
<PrismicLink>
// 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.
<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.
<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.
<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.
<PrismicLink :field="document.data.myLinkField" target="_top" rel="noopener">
Click me
</PrismicLink>
<PrismicImage>
// 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.
<PrismicImage :field="document.data.myImageField" />
<PrismicEmbed>
// 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.
<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.
<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.
/* 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>
// 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.
<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.
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 slice objects in the slice zone.context
: Arbitrary data passed to the<SliceZone>
’scontext
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.
<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.
<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.
<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.
<SliceZone
:slices="document.data.body"
:components="{
text: TextSlice,
images: ImagesSlice,
}"
wrapper="article"
/>