├── .browserslistrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── babel.config.js ├── custom_types ├── index.json └── page.json ├── package-lock.json ├── package.json ├── public ├── favicon.png └── index.html ├── src ├── App.vue ├── assets │ ├── css │ │ ├── prismic-edit-button.css │ │ ├── resetr.css │ │ └── tutorial │ │ │ ├── highlight.min.css │ │ │ └── tutorial.min.css │ └── img │ │ ├── prismic-logo.svg │ │ ├── tutorial │ │ ├── bb.gif │ │ ├── chevron.svg │ │ ├── open.svg │ │ └── rocket.svg │ │ └── vue-logo.png ├── components │ └── FooterPrismic.vue ├── main.js ├── prismic │ ├── html-serializer.js │ └── link-resolver.js ├── router.js └── views │ ├── NotFound.vue │ ├── Preview.vue │ └── Tutorial.vue └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prismic Vue.js Starter 2 | 3 | > [Vue.js](https://vuejs.org) starter project with content managed in [Prismic](https://prismic.io) 4 | 5 | ## How to launch this project in your local environment 6 | 7 | Run the following commands: 8 | 9 | ``` bash 10 | npm install 11 | npm run serve 12 | ``` 13 | 14 | Then you can access it at [http://localhost:8080](http://localhost:8080). 15 | You'll find a tutorial that explains how to create your first Vue component filled with content retrieved from Prismic. 16 | 17 | ## How to remove the tutorial from this project 18 | 19 | - Remove Tutorial import and route in src/router/index.js 20 | - Delete Tutorial component file `rm src/views/Tutorial.vue` 21 | - Delete Tutorial assets `rm -r src/assets/css/tutorial/ && rm -r src/assets/img/tutorial/` 22 | - Remove vue-highlightjs dependency `npm uninstall vue-highlightjs` 23 | 24 | ## Project setup 25 | ``` bash 26 | npm install 27 | ``` 28 | 29 | ### Compiles and hot-reloads for development 30 | ``` bash 31 | npm run serve 32 | ``` 33 | 34 | ### Compiles and minifies for production 35 | ``` bash 36 | npm run build 37 | ``` 38 | 39 | ### Lints and fixes files 40 | ``` bash 41 | npm run lint 42 | ``` 43 | 44 | ## License 45 | 46 | This software is licensed under the Apache 2 license, quoted below. 47 | 48 | Copyright 2013-2018 Prismic (http://prismic.io). 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 51 | 52 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 53 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /custom_types/index.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": "page", 3 | "name": "Page", 4 | "repeatable": true, 5 | "value": "page.json" 6 | }] -------------------------------------------------------------------------------- /custom_types/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "Main" : { 3 | "uid" : { 4 | "type" : "UID", 5 | "config" : { 6 | "placeholder" : "UID...", 7 | "label" : "UID" 8 | } 9 | }, 10 | "title" : { 11 | "type" : "StructuredText", 12 | "config" : { 13 | "single" : "heading1", 14 | "label" : "Title", 15 | "placeholder" : "Title..." 16 | } 17 | }, 18 | "description" : { 19 | "type" : "StructuredText", 20 | "config" : { 21 | "multi" : "paragraph, heading2, strong, em, hyperlink", 22 | "allowTargetBlank" : true, 23 | "label" : "Description", 24 | "placeholder" : "Description..." 25 | } 26 | }, 27 | "cta_link" : { 28 | "type" : "Link", 29 | "config" : { 30 | "allowTargetBlank" : true, 31 | "label" : "CTA link", 32 | "placeholder" : "CTA link..." 33 | } 34 | }, 35 | "cta_text" : { 36 | "type" : "StructuredText", 37 | "config" : { 38 | "single" : "paragraph", 39 | "label" : "CTA text", 40 | "placeholder" : "CTA text..." 41 | } 42 | }, 43 | "icon" : { 44 | "type" : "Image" 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prismic-vuejs-starter", 3 | "version": "1.2.0", 4 | "description": "Vue.js starter project with content managed in Prismic", 5 | "license": "Apache-2.0", 6 | "repository": "github:prismicio/vuejs-starter", 7 | "author": "Prismic", 8 | "scripts": { 9 | "serve": "vue-cli-service serve", 10 | "build": "vue-cli-service build" 11 | }, 12 | "dependencies": { 13 | "prismic-dom": "^2.1.0", 14 | "prismic-vue": "^1.3.0", 15 | "vue": "^2.5.16", 16 | "vue-highlightjs": "^1.3.3", 17 | "vue-router": "^3.0.1" 18 | }, 19 | "devDependencies": { 20 | "@vue/cli-plugin-babel": "^3.0.0-rc.5", 21 | "@vue/cli-service": "^3.0.0-rc.5", 22 | "vue-template-compiler": "^2.5.16" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/vuejs-starter/80f73e7883c834ec298cf80ff7f9e4b3f0f266f5/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |${result}
` 44 | return result 45 | } 46 | 47 | // Return null to stick with the default behavior for everything else 48 | return null 49 | } 50 | -------------------------------------------------------------------------------- /src/prismic/link-resolver.js: -------------------------------------------------------------------------------- 1 | /** 2 | * To learn more about Link Resolving check out the Prismic documentation 3 | * https://prismic.io/docs/vuejs/beyond-the-api/link-resolving 4 | */ 5 | 6 | export default function (doc) { 7 | if (doc.isBroken) { 8 | return '/not-found' 9 | } 10 | 11 | if (doc.type === 'home') { 12 | return '/' 13 | } 14 | 15 | if (doc.type === 'page') { 16 | return '/page/' + doc.uid 17 | } 18 | 19 | return '/not-found' 20 | } 21 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import NotFound from './views/NotFound.vue' 4 | import Preview from './views/Preview.vue' 5 | import Tutorial from './views/Tutorial.vue' 6 | 7 | Vue.use(Router) 8 | 9 | export default new Router({ 10 | mode: 'history', 11 | routes: [ 12 | { 13 | path: '/', 14 | redirect: { name: 'tutorial' } 15 | }, 16 | { 17 | path: '/not-found', 18 | name: 'not-found', 19 | component: NotFound 20 | }, 21 | { 22 | path: '/preview', 23 | name: 'preview', 24 | component: Preview 25 | }, 26 | { 27 | path: '/tutorial', 28 | name: 'tutorial', 29 | component: Tutorial 30 | }, 31 | { 32 | path: '*', 33 | redirect: { name: 'not-found' } 34 | } 35 | ] 36 | }) 37 | -------------------------------------------------------------------------------- /src/views/NotFound.vue: -------------------------------------------------------------------------------- 1 | 2 |Not Found
4 |Loading the Prismic's Preview...
4 |Grab a well deserved cup of coffee, you’re just a few steps away from creating a Vue.js component with content managed in Prismic.
13 |This is a tutorial page included in this Vue.js starter project, it has a few useful links and example code snippets to help you get started.
34 |You can access this very tutorial page at http://localhost:8080/tutorial.
35 | 36 |A repository is where your website’s content will live. Simply create one choosing a repository name and a plan. We’ve got a variety of plans including our favorite: Free!
41 |Open the index.html file and define the API endpoint of your Prismic repository:
43 |<!-- In public/index.html -->
44 |
45 | <script>
46 | window.prismic = {
47 | endpoint: 'https://your-repo-name.prismic.io/api/v2'
48 | }
49 | </script>
50 |
51 | Next let’s see how to create a Vue component filled with content retrieved from Prismic.
52 | 53 |We’ll create a document containing a title, a description, a call to action and an icon. Let’s create a Custom Type in Prismic with the corresponding fields. We’ll add an additional UID field (unique identifier) for querying the document.
55 |Go to the Web interface of the Prismic repository you’ve just created (at https://your-repo-name.prismic.io). Then navigate to the "Custom Types" section (icon on the left navbar) and create a new Repeatable Type, for this tutorial let’s name it "Page", so that its API ID will be set to "page".
56 |Once the "Page" Custom Type is created, we have to define how we want to model it, that is to say a document containing a UID field, a rich text field for the title, a rich text field for the description, a link field + a rich text field for the call to action and an image field for the icon. Click on "JSON editor" (right sidebar) and paste in the following JSON data.
57 |When you’re done, hit "Save".
58 |{
59 | "Main": {
60 | "uid": {
61 | "type": "UID",
62 | "config": {
63 | "placeholder": "UID...",
64 | "label": "UID"
65 | }
66 | },
67 | "title": {
68 | "type": "StructuredText",
69 | "config": {
70 | "single": "heading1",
71 | "label": "Title",
72 | "placeholder": "Title..."
73 | }
74 | },
75 | "description": {
76 | "type": "StructuredText",
77 | "config": {
78 | "multi": "paragraph, heading2, strong, em, hyperlink",
79 | "allowTargetBlank": true,
80 | "label": "Description",
81 | "placeholder": "Description..."
82 | }
83 | },
84 | "cta_link": {
85 | "type": "Link",
86 | "config": {
87 | "allowTargetBlank": true,
88 | "label": "CTA link",
89 | "placeholder": "CTA link..."
90 | }
91 | },
92 | "cta_text": {
93 | "type": "StructuredText",
94 | "config": {
95 | "single": "paragraph",
96 | "label": "CTA text",
97 | "placeholder": "CTA text..."
98 | }
99 | },
100 | "icon": {
101 | "type": "Image"
102 | }
103 | }
104 | }
105 |
106 |
107 | Now it is time to fill in and publish your first "Page" document in your Prismic repository.
109 |110 | Create a new "Page" document in your repository: go to "Content" and hit "New". 111 | Fill the corresponding fields. Note the value you filled in the UID field, because it will be a part of the component route path, for this tutorial let’s put "quickstart". 112 |
113 |When you’re done, hit "Save" then "Publish".
114 | 115 |Let’s create a Vue component that will display content fetched from the Prismic API.
119 |Go back to your local code and create a new Vue component file named "Page.vue" inside the views folder (src/views/Page.vue). We’ll make an API call to retrieve the document content, querying it by specifying its UID.
120 |Here’s an example that’ll render a "Page" document with its title, description, call to action and icon:
121 |<!-- Create file src/views/Page.vue -->
122 |
123 | <template>
124 | <div class="wrapper">
125 | <prismic-edit-button :documentId="documentId"/>
126 | <h1 class="title">
127 | {{ "\{\{ $prismic.richTextAsPlain(fields.title) \}\}" }}
128 | </h1>
129 | <prismic-rich-text :field="fields.description" class="description"/>
130 | <div class="cta-wrapper">
131 | <prismic-link :field="fields.ctaLink" class="cta">
132 | {{ "\{\{ $prismic.richTextAsPlain(fields.ctaText) \}\}" }}
133 | </prismic-link>
134 | </div>
135 | <div class="icon-wrapper">
136 | <prismic-image :field="fields.icon" class="icon"/>
137 | </div>
138 | </div>
139 | </template>
140 |
141 | <script>
142 | export default {
143 | name: 'Page',
144 | data () {
145 | return {
146 | documentId: '',
147 | fields: {
148 | title: null,
149 | description: null,
150 | ctaLink: null,
151 | ctaText: null,
152 | icon: null
153 | }
154 | }
155 | },
156 | methods: {
157 | getContent (uid) {
158 | this.$prismic.client.getByUID('page', uid)
159 | .then((document) => {
160 | if (document) {
161 | this.documentId = document.id
162 | this.fields.title = document.data.title
163 | this.fields.description = document.data.description
164 | this.fields.ctaLink = document.data.cta_link
165 | this.fields.ctaText = document.data.cta_text
166 | this.fields.icon = document.data.icon
167 | } else {
168 | this.$router.push({ name: 'not-found' })
169 | }
170 | })
171 | }
172 | },
173 | created () {
174 | this.getContent(this.$route.params.uid)
175 | },
176 | beforeRouteUpdate (to, from, next) {
177 | this.getContent(to.params.uid)
178 | next()
179 | }
180 | }
181 | </script>
182 |
183 | <style>
184 | .wrapper {
185 | max-width: 820px;
186 | margin-left: auto;
187 | margin-right: auto;
188 | padding: 40px 10px;
189 | font-family: Avenir, "Helvetica Neue", Helvetica, Arial, sans-serif;
190 | }
191 |
192 | .title {
193 | font-size: 32px;
194 | }
195 |
196 | .description {
197 | margin-top: 40px;
198 | }
199 |
200 | .description h2 {
201 | font-size: 24px;
202 | }
203 |
204 | .description h2:not(:first-child) {
205 | margin-top: 20px;
206 | }
207 |
208 | .description p {
209 | line-height: 1.5;
210 | }
211 |
212 | .description p:not(:first-child) {
213 | margin-top: 10px;
214 | }
215 |
216 | .description a {
217 | color: #404e9f;
218 | }
219 |
220 | .description a:hover {
221 | text-decoration: underline;
222 | }
223 |
224 | .cta-wrapper {
225 | margin-top: 40px;
226 | }
227 |
228 | .cta {
229 | display: inline-flex;
230 | justify-content: center;
231 | align-items: center;
232 | height: 40px;
233 | padding: 0 20px;
234 | background-color: #404e9f;
235 | color: white;
236 | }
237 |
238 | .icon-wrapper {
239 | margin-top: 40px;
240 | }
241 |
242 | .icon {
243 | max-width: 100%;
244 | }
245 | </style>
246 |
247 |
248 | Now that you’ve created your Page component, add the following route to the Vue Router, in src/router.js file:
250 |// In src/router.js
251 |
252 | // ...
253 |
254 | import Page from './views/Page.vue'
255 |
256 | // ...
257 |
258 | {
259 | path: '/page/:uid',
260 | name: 'page',
261 | component: Page
262 | },
263 |
264 | // ...
265 |
266 |
267 | In your browser go to http://localhost:8080/page/quickstart and voilà! You’ve officially created a Vue component that pulls content from Prismic.
268 | 269 |Sit back and enjoy the result.
271 |Basically in these few steps you’ve added content management to your Vue.js project and thanks to Prismic, you’ll have:
272 |