Open studiolathe opened 1 year ago
@alexjoverm any ideas why this might be happening?
cc @manuelschroederdev @alexjoverm
Very interesting issue @studiolathe! Judging by the error you're getting, seems like the issue it's at Storyblok Bridge level, so it's possible there is an issue there. That'd explain that you're also having the issue regardless on the SDK version. Is it possible for you to share something reproducible? A Stackblitz link would be very appreciated, so @Dawntraoz and I can investigate
Hi @alexjoverm
Thanks so much for getting back to me!
I have spent quite a bit of time stepping back through old commits to try and find if something changed that would be triggering this bug and I think I have found the culprit!
So... we were previously making all requests with the Preview access token and setting the request version to "Draft", see example below:
// pages/index.vue
asyncData: async () => {
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get("cdn/stories/home", {
version: "draft",
});
return { story: data.story };
},
But it seemed we facing some caching issues with our Netlify builds so we switched to using the Public access token and updated all requests to version: "published"
and it looks like these settings are the culprit that breaks the Live Preview and triggers the error.
I have now reverted all requests to use version: "draft"
and changed the main Storyblok config back to the Preview token and Live Preview seems to working as expected.
Do we know why the published version might be causing this and what is best practice for making in requests in a production site, should we use the Preview or Public token?
I have added the nuxt.config.js
, package.json
and index.vue
so you can see the setup:
nuxt.config.js
import path from 'path'
import fs from 'fs'
// import axios from 'axios'
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'XXXX',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: XXXX' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' },
{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '192x192', href: '/android-chrome-192x192.png' },
{ rel: 'icon', type: 'image/png', sizes: '512x512', href: '/android-chrome-512x512.png' },
{ rel: 'icon', type: 'apple-touch-icon', href: '/apple-touch-icon.png' },
{ rel: 'manifest', href: '/site.webmanifest' }
],
script: [
{
hid: "hs-script-loader",
src: "//js.hs-scripts.com/XXXX.js",
defer: true,
},
],
},
loading: {
color: '#64BE78',
height: '2px',
throttle: 0
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
'@assets/scss/main.scss'
],
// SCSS
styleResources: {
scss: [
'@assets/scss/base/_02-mixins.scss',
'@assets/scss/base/_03-variables.scss',
'@assets/scss/base/_04-helpers.scss',
]
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: '@/plugins/vue-observe-visibility' },
{ src: '@/plugins/v-lazy-image' },
{ src: '@/plugins/vue-scrollactive', mode: 'client' },
{ src: '@/plugins/vuelidate' },
{ src: '@/plugins/lottie-vue-player.client.js' },
{ src: '@/plugins/google-gtag.client.js', mode: 'client' },
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
'@nuxtjs/style-resources',
'@nuxt/image',
["@storyblok/nuxt-2/module", {
accessToken: process.env.STORYBLOK_PREVIEW_API_TOKEN,
// bridge: true, Has no effect?
// useApiClient: true, Has no effect?
apiOptions: {
cache: {
type: "memory"
}
},
}],
'@nuxtjs/composition-api/module',
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
'@nuxtjs/svg',
'@nuxtjs/sitemap',
'@nuxtjs/robots',
[
'nuxt-vuex-localstorage',
{
localStorage: ['cookies'],
// expiration time in hours
expire: 24 * 30,
}
],
],
// Nuxt Image: https://image.nuxtjs.org/providers/storyblok
image: {
storyblok: {
baseURL: 'https://a.storyblok.com'
}
},
// Public Runtime Config
publicRuntimeConfig: {
storyblokApiToken: process.env.STORYBLOK_PREVIEW_API_TOKEN,
hubspotFormId: process.env.HUBSPOT_FORM_ID,
hubspotPortalId: process.env.HUBSPOT_PORTAL_ID,
g4Id: process.env.G4_ID
},
generate: {
// Helps Netlify with 404 handling by generating a 404.html page
fallback: true,
// Exclude dynamic routes from static generation if using default Nuxt crawler
// exclude: [
// /^\/global/
// ],
routes: function (callback) {
const token = process.env.STORYBLOK_PREVIEW_API_TOKEN
const version = 'published'
const axios = require('axios');
let cache_version = 0
// Routes to exclude from static generation
let toIgnore = ['home', 'posting', 'global', 'global/nav', 'global/menu', 'global/footer', 'global/error', 'global/cookies']
// Other routes that are not in Storyblok with their slug.
let routes = ['/'] // adds / directly
// Load space and receive latest cache version key to improve performance
axios.get(`https://api.storyblok.com/v1/cdn/spaces/me?token=${token}`).then((space_res) => {
// timestamp of latest publish
cache_version = space_res.data.space.version
// Call for all Links using the Links API: https://www.storyblok.com/docs/Delivery-Api/Links
axios.get(`https://api.storyblok.com/v1/cdn/links?token=${token}&version=${version}&cv=${cache_version}&per_page=100`).then((res) => {
Object.keys(res.data.links).forEach((key) => {
if (!toIgnore.includes(res.data.links[key].slug)) {
routes.push('/' + res.data.links[key].slug)
}
})
callback(null, routes)
})
})
}
},
// Add trailing slash to our internal links in prod for Netlify (Storyblok preview won't resolve with trailing slash)
router: {
trailingSlash: process.env.NODE_ENV === 'development' ? undefined : true,
},
// Sitemap config
sitemap: {
hostname: 'https://www.example.com',
defaults: {
changefreq: 'monthly',
priority: 1,
trailingSlash: true
},
trailingSlash: true,
},
// Robots.txt config
robots: {
UserAgent: '*',
Disallow: () => (process.env.NODE_ENV === 'development') ? '/' : '' // Disallow everything in dev
},
// Server
server: {
https: process.env.NODE_ENV === 'development' ? {
key: fs.readFileSync(path.resolve(__dirname, 'key.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'cert.pem'))
} : false,
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
baseURL: '/',
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
// ES Modules
standalone: true,
transpile: [
'@nuxtjs/composition-api',
'@storyblok/nuxt-2'
],
extend(config) {
config.module.rules.push({
test: /\.(cjs|mjs)$/,
exclude: {
and: [/node_modules/],
not: [/pathe/]
},
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', { targets: 'ie 11' }]]
}
}
})
}
}
}
package.json (note this is working with "@storyblok/nuxt-2": "^1.1.0"
{
"name": "XXXX",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt dev --https --ssl-cert localhost.pem --ssl-key localhost-key.pem",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/robots": "^2.5.0",
"@nuxtjs/sitemap": "^2.4.0",
"@nuxtjs/style-resources": "^1.2.1",
"@nuxtjs/svg": "^0.4.0",
"core-js": "^3.19.3",
"intersection-observer": "^0.12.2",
"nuxt": "^2.15.8",
"nuxt-polyfill": "^1.0.3",
"nuxt-vuex-localstorage": "^1.3.0",
"swiper": "6.8.4",
"v-lazy-image": "^1.4.0",
"vue-awesome-swiper": "^5.0.1",
"vue-gtag": "1.16.1",
"vue-observe-visibility": "^1.0.0",
"vue-scrollactive": "^0.9.3",
"vue-select": "^3.20.0",
"vue-server-renderer": "^2.6.14",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.46.0"
},
"devDependencies": {
"@lottiefiles/vue-lottie-player": "^1.0.9",
"@nuxt/image": "^0.7.1",
"@nuxtjs/composition-api": "^0.33.1",
"@storyblok/nuxt-2": "^1.1.0",
"sass": "^1.54.3",
"sass-loader": "10",
"vuelidate": "^0.7.7"
}
}
pages/index.vue
<template>
<StoryblokComponent v-if="story" :blok="story.content" />
</template>
<script>
import { useStoryblokBridge, useStoryblokApi } from "@storyblok/nuxt-2";
export default {
asyncData: async () => {
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get("cdn/stories/home", {
version: "draft",
// version: "published" - This doesn't work with Public token
});
return { story: data.story };
},
computed: {
seo() {
if (this.story) {
return this.story.content;
}
},
},
mounted() {
useStoryblokBridge(this.story.id, (newStory) => (this.story = newStory));
},
};
</script>
Please let me know your thoughts on best approach and if theres any improvements we can be making to the config?
Thanks in advance!
Hi, any progress on this issue? I've got the same scenario where using the Public key causes the above mentioned error in the live preview. Using the Preview key for a production site isn't really an option for me.
Edit; Maybe I'm missing something with the configuration; should the Preview key somehow be used only when the project is rendered in the live preview window? I've got my access tokens defined in env variables, so they're pretty static once the project is deployed.
@frans-vectra I am doing the same. I have the access token in env. I don't think there is a solution to have two different tokens so I guess the only option is to use the same key for both preview and live. It seems like the same applies for the nuxt3 module.
@Dawntraoz are we missing something? I had a discussion today with my team and the only option we have is to obscure all the request to a server api middleware that proxies the requests. Not ideal!
Hi folks @studiolathe, @frans-vectr, @SebbeJohansson, I think I may have found what is happening after double-checking your issue.
The idea behind the Preview
and Public Token
is that if you have a site for creating/previewing the content separated (deployed in another instance) from the production one, you will use Preview
for the previewing environment and Public
for the production one.
But as you're using the same site for previewing and publishing the content, then you will need to use the Preview Token
and make a conditional like the following to change between draft
and published
if you're inside the editor or not:
asyncData: async (context) => {
const storyblokApi = useStoryblokApi();
// This is how we get that we are inside the Storyblok space:
const version =
context.query._storyblok || context.isDev ? 'draft' : 'published';
const { data } = await storyblokApi.get("cdn/stories/home", {
version,
});
return { story: data.story };
},
I hope this clarifies what is happening. Let me know if it works in your cases and if you think it will be worth it to add it to the Readme π
@Dawntraoz In my case, that doesn't fully fix our issue. Since we want to limit what actual Token
is used, we would need two tokens inside the application.
Not sure if this is off-topic for this issue, but is there any documentation for handling "obscuring" the storyblok calls so that they are not shown on the client? Both for draft
and for published
content. If not, I've got something to figure out!
@SebbeJohansson I think you're right. That should not be part of this issue since the Visual Editor works.
Maybe it's better to open a "question" tag issue and we can discuss it there π
@Dawntraoz Im not sure if you meant in the general repo, or on here. I made it here since I need a suggestion specifically for nuxt2 (since this is a work question π). https://github.com/storyblok/storyblok-nuxt-2/issues/103
Has anyone had this problem occur for certain blocks on the page but not all of them? We are fetching the draft
version of the story while preview mode is active. Indeed, the data-blok-c
and data-blok-uid
are undefined
for these blocks.
Hi there
I am using
storyblok-nuxt-2@^1.0.2
with Nuxt 2 (^2.15.8
) and the Live Preview editor (V2) is no longer working (when it previously was). When inspecting the console inside the Storyblok editor I noticed I am receiving the below error on every click inside the preview:On inspection of the rendered component HTML elements and it seems I am getting
undefined
on thedata-blok-c
anddata-blok-uid
attributes on all of the Storyblok rendered components:For further context, see the
nuxt.config.js
and page components:For additional context the preview was working and I have multiple projects using the same setup with no issues and inspecting the rendered elements displays the data attributes being rendered with Storyblok data..
Is this an issue related to my setup, the
StoryblokComponent
or withstoryblok-v2-latest.js
.FYI I have tested with the latest
storyblok-nuxt-2@^1.0.2
and the issues persists.Any help would be greatly appreciated!
Thanks in advance.