Nuxt3 data fetching not working after client-side navigation - nuxtjs3

I am working on a Nuxt3 app locally. I have a page component [slug].vue page component for blog posts which fetches data from a Strapi endpoint. When I navigate from the home page to a blog post via <nuxt-link> I get an empty page. When I reload the page in the browser, the data gets displayed. At this point I am kinda lost and don't know what's wrong. Here is the code of the [slug].vue
<template>
<section id="start" class="min-h-screen flex items-center">
<LayoutMoContainer is-narrow>
<div v-if="pending">
Loading ...
</div>
<div v-else>
<div v-if="post">
<AtomsMoHeadline v-if="post.title" class="text-center" headline-type="h1" :text="post.title" />
<div v-if="post.content" class="dark:text-white">
<div v-html="post.content"></div>
</div>
</div>
</div>
</LayoutMoContainer>
</section>
</template>
<script lang="ts" setup>
/**
* Fetch posts
*/
const config = useRuntimeConfig();
const STRAPI_URL = config.STRAPI_URL;
const route = useRoute();
const slug = route.params.slug;
const { pending, data: post } = await useLazyAsyncData('post', () => $fetch(`${STRAPI_URL}articles/${slug}`), { server: false });
</script>
Nuxt Project Info
- Operating System: `Darwin`
- Node Version: `v18.7.0`
- Nuxt Version: `3.0.0-rc.6`
- Package Manager: `yarn#1.22.19`
- Builder: `vite`
- User Config: `publicRuntimeConfig`, `app`, `css`, `buildModules`, `build`, `vite`
- Runtime Modules: `-`
- Build Modules: `#pinia/nuxt#0.3.1`

The problem was due to a page component having more than one root element.

Related

NextJs Script not rendering inside component

I am trying to implement Cookiebot on my NextJs Website.
The docs (Link to docs) mention to insert the script for the cookie declaration inside the HTML of the specific page, for me it is an own subpage only for the cookie declaration.
If I use the HTML element <script ... /> as mentioned in the docs, the text does not load when I switch to the page, but only after a refresh once I'm on the page.
If I use the NextJs Script component Link to docs by switching the <script ..> to and import it from next/script, the cookie declaration loads instantly as expected, but it is placed below everything else of the page, even under the footer (even though i wrap the pages inside a layout with footer).
My code for the layout looks like following:
`
function BasePage(props: IBasePageProps) {
return (
<div>
<Navbar />
<main>{props.children}</main>
<Footer />
</div>
);
}
This works for every page and everything - the pages are all between the Navbar and Footer. However if I use following code for the page of the screenshot, the <Script .../> text is loaded below the footer.
export default function CookieRichtlinie() {
return (
<>
<h1 className="pb-8 mt-2 text-3xl font-extrabold leading-8 tracking-tight text-gray-900 sm:text-4xl">
Cookie Richtlinie
</h1>
<div id="CookiePolicyText">
<Script
id="CookieDeclaration"
src="https://consent.cookiebot.com/12345/cd.js"
type="text/javascript"
async
/>
</div>
</>
);
`
After googling for two days I couldn't find any issue or thread close to this problem. Someone experienced this or know what I could try?
<Script ...> below everything else
Placed <Script ...> tag of next/script anywhere possible to get the loaded text inside the page. Expected to have the result of the script in the placed component, however it is always at the bottom of the page.
Did some global searches in Github and found an useEffect workaround, made some modifications and this worked in my case.
useEffect(() => {
const cookieBotWrapper = document.getElementById("CookiebotDeclaration")
if (cookieBotWrapper) {
const script = document.createElement("script")
script.id = "CookieDeclaration"
script.type = "text/javascript"
script.async = true
script.src = `https://consent.cookiebot.com/${process.env.NEXT_PUBLIC_COOKIEBOT_DOMAIN_GROUP_ID}/cd.js`
cookieBotWrapper.appendChild(script)
}
}, [])
return (
<main>
{process.env.NODE_ENV !== "development" && (
<div id="CookiebotDeclaration" />
)}
</main>
)

how to fix nextjs prerender error - vercel deployment?

How do I troubleshoot this problem this deployment issue? I am following this tutorial. My node_modules and .next are ignored and not pushed to github. It works locally but can't seem to deploy. I have supplied both the component code as well as the page it's exported on. Let me know if you can see what I am missing.
https://www.youtube.com/watch?v=V4SVNleMitE
deployment errors
Error occurred prerendering page "/components/BlogPosts". Read more: https://nextjs.org/docs/messages/prerender-error
TypeError: Cannot read property 'fields' of undefined
at BlogPosts (/vercel/path0/.next/server/chunks/130.js:39:12)
at d (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:33:498)
at bb (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
at a.b.render (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
at a.b.read (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
at Object.exports.renderToString (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
at Object.renderPage (/vercel/path0/node_modules/next/dist/server/render.js:673:46)
at Object.defaultGetInitialProps (/vercel/path0/node_modules/next/dist/server/render.js:315:51)
at Function.getInitialProps (/vercel/path0/.next/server/pages/_document.js:645:16)
at Object.loadGetInitialProps (/vercel/path0/node_modules/next/dist/shared/lib/utils.js:69:29)
component blog posts
export default function BlogPosts({post }) {
const {title, information,slug , thumbnail} = post.fields
return (
<div>
<div className='container w-50 h-25 mt-4'>
<Image
className='nav'
src={'https:' + thumbnail.fields.file.url}
width={thumbnail.fields.file.details.image.width}
height={thumbnail.fields.file.details.image.height}
/>
</div>
<div>
<div>
<h4 className=''>{title}</h4>
<Link href={'/contentslug/' + slug}>
<a className='btn btn-primary text-white'>Read more</a>
</Link>
</div>
</div>
</div>
)
}
Pages/Posts
import {createClient} from 'contentful'
import BlogPosts from './components/BlogPosts'
import Nav from './components/Nav'
import Logo from './components/Logo'
export async function getStaticProps() {
const client = createClient({
space: process.env.NEXT_PUBLIC_CONTENTFUL_ID,
accessToken: process.env.NEXT_PUBLIC_CONTENTFUL_TOKEN,
})
const res = await client.getEntries({content_type: 'posts'})
return {
props: {
posts: res.items ,
revalidate: 1
}
}
}
export default function Home({posts}) {
console.log(posts);
return (
<div>
<Logo/>
<Nav/>
<div className="container text-center display-5">
{posts.map(post => (
<BlogPosts key={post.sys.id} post={post}/>
))}
</div>
</div>
)
}
You have fields of undefined. this might be caused because of some strange deploying behavior if you are 100% sure your code works.
How to fix (probably):
Build your project locally. if it works, follow the next step
Comment your code in BlogPosts, inside the exported component. The code must work, so your exported component will be empty but working.
Push this code to Vercel.
Uncommit your code. (done at point 2)
Push again.
P.S. this behavior with API is sometimes caused because of API middleware you reworked.

instafeedjs loads once only then images disappear! Ruby on Rails 4

I am using instafeedjs to display images on a simple website I am building and it works great when the page is first loaded. If I navigate away from that page and then come back via navbar "home" button the images won't load/disappear, unless I refresh the page. Has anyone else had this issue and know of a fix? I think it has to do with cache but don't know the workaround. Also I am working in ruby on rails 4. Thanks!
Here is the code I have on the view page:
<section>
<div class="container">
<header>
<div class="instafeed-content">
<h2 class="text-center">Follow on Instagram</h2>
<div class="row">
<div id="instafeed"></div>
</div>
<div class="clearfix"></div>
</div>
</header>
</div>
</section>
Here is the code displaying the script inside my application.html.erb:
I have removed the info for userId, clientId, and accessToken but they are filled in properly in the code.
var userFeed = new Instafeed({
get: 'user',
userId: '...',
target: 'instafeed',
accessToken: '...',
clientId: '...',
resolution: 'low_resolution',
limit: 4,
sortBy: 'most-liked',
template: '',
});
userFeed.run();
I hope this helps!

VueJS component won't render on front end (possibly Drupal issue)

The site I'm currently working on is built in Drupal 7. I have one form that requires user input so I'm attempting to build it with VueJS. The form is contained all within one template file (.tpl.php) and all the content is provided in this template file or via the VueJS Javascript (nothing is coming from the CMS).
The issue I have is that the Vue components are not rendering on the front-end, but when I copy the code into a JSFiddle they do, so I'm guessing it is an issue with the interaction between VueJS and Drupal. Here is a screenshot of my markup when inspecting...
Here is the code from the .tpl.php file...
<div id="app">
<form>
<div>
<label for="year">Per Year</label>
<input type="radio" name="frequency" id="year" value="year" v-model="frequency" checked>
<label for="month">Per Month</label>
<input type="radio" name="frequency" id="month" value="month" v-model="frequency">
</div>
</form>
<ul class="plans">
<template id="plan-component">
<h2 class="plan-name">{{ name }}</h2>
<h2 class="plan-cost">{{ price }}</h2>
<h2 class="plan-tagline">{{ tagline }}</h2>
Choose this plan
</template>
<li>
<plan-component :frequency="frequency"
name="Basic"
tagline="Basic tagline"
price-yearly="Free"
price-monthly="Free"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Rec"
tagline="Rec tagline"
price-yearly="3"
price-monthly="4"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Team"
tagline="Team tagline"
price-yearly="4"
price-monthly="5"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Club"
tagline="Club tagline"
price-yearly="5"
price-monthly="6"
></plan-component>
</li>
</ul>
</div>
..and the code from my JS file...
Vue.component('plan-component', {
template: '#plan-component',
props: ['frequency', 'name', 'tagline', 'priceYearly', 'priceMonthly'],
computed: {
'price': function() {
if (this.frequency === 'year') {
return this.priceYearly;
} else {
return this.priceMonthly;
}
}
},
methods: {
makeActivePlan() {
// We dispatch an event setting this to become the active plan
this.$dispatch('set-active-plan', this);
}
}
});
new Vue({
el: '#app',
data: {
frequency: 'year',
activePlan: {name: 'no', price: 'You must select a plan!' }
},
events: {
'set-active-plan': function(plan) {
this.activePlan = plan;
}
},
});
And here is the JSFiddle which outputs the components correctly - https://jsfiddle.net/2xgrpLm6/
What browser are you using? <template> tags are not supported in IE.
Another idea is to make sure you are never using fragment components (meaning wrap everything inside your template with a div like so:
<template id="foobar">
<div>
CONTENT HERE
</div>
</template>
Lastly, have you turned on Vue debug mode? Before you instantiate your Vue instance, set Vue.config.debug = true and see if you get console errors then.
Try moving the <template id="plan-component">...</template> code outside of the Vue instance. I.e., such that it is not contained within <div id="app">...</div>.
This has solved a similar problem for me in the past, though I'm not sure if it applies here.
For anyone having a similar issue, the solution was simple. After Jeff suggested turning on Vue debug mode (and downloading the Dev version of Vue JS instead of minified - https://vuejs.org/guide/installation.html) the console gave the error [Vue warn]: Cannot find element: #app.
The issue was that Drupal was loading my scripts in the <head>, before <div id="app"> was loaded in the DOM. As such #app couldn't be found. After outputting the scripts before the closing <body> tag all was sorted. See here for more information [Vue warn]: Cannot find element

Accessing Firebase from Polymer Element

I am working on an app that uses Polymer and Firebase. I am trying to figure out how to access my Firebase document from my custom element. Currently, I have a view defined like this:
<body>
<template is="dom-bind" id="dialog">
<firebase-document location="https://my-app.firebaseio.com/" data="{{ orders }}"></firebase-document>
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<section data-route="home">
<h3>Hello</h3>
</section>
<section data-route="orders">
<h3>Orders</h3>
<user-orders orders="{{ orders }}"></user-orders>
</section>
</iron-pages>
</template>
</body>
The user-orders element is defined like this:
<dom-module id="user-orders">
<template>
<template is="dom-repeat" items="[[ orders ]]" as="order">
<div>[[ order.date ]]</div>
<div>[[ order.status ]]</div>
<div>[[ order.description ]]</div>
</template>
<button on-click="test">Test</button>
<button>Add New Order</button>
</template>
<script>
Polymer({
is: "user-orders",
properties: {
orders: {
type: Array,
notify: true,
value: function() {
return [];
}
}
},
test: function() {
alert(JSON.stringify(this.orders));
}
})
</script>
</dom-module>
The view associated with my route appears correctly. However, when I click my "Test" button, an alert window appears that says null. Its like either a) I've setup my firebase connection improperly, which I'm not sure how to actually confirm or b) My data binding is setup improperly.
What am I doing wrong?
Are you working with a brand new Firebase app or an existing Firebase app? A brand new Firebase app without any data will return null.

Resources