Calendly widget doesn't work after page refresh when live - vue.js

The calendly widget works at first, but if you refresh the page it stops working but only when the website is live. In local development, no such issue occurs.
Also noticed that when I route to the page through navigation, it works. But if I enter the link to the specific page directly, it doesn't work.
Here's the code:
<template>
<client-only>
<vue-calendly url="link" :height="650"></vue-calendly>
</client-only>
</template>
<script>
import Vue from 'vue';
export default {
created() {
if (process.isClient) {
const VueCalendly = require('vue-calendly').default;
Vue.use(VueCalendly);
}
}
};
</script>
The Vue application is running on Gridsome so it's SSR. I set the widget to only display in client side. Not sure what the issue is.

There is a solution possible to integrate Calendly without using their widget. You can try it as well. This solution should not produce the error mentioned and was tried in an SSR application.
<template>
<!-- Calendly inline widget begin -->
<div class="calendly-inline-widget" data-url="YOUR_CALENDLY_URL" style="min-width:320px;height:630px;"></div>
<!-- Calendly inline widget end -->
</template>
<script>
export default {
mounted () {
const recaptchaScript = document.createElement('script')
recaptchaScript.setAttribute('src', 'https://assets.calendly.com/assets/external/widget.js')
document.head.appendChild(recaptchaScript)
}
}
</script>

From this link, we can see that he is importing the component with
import Vue from 'vue';
import VueCalendly from 'vue-calendly';
Vue.use(VueCalendly);
Then with
<vue-calendly url="your Calendly URL" :height="600"></vue-calendly>
I'm not sure if you are trying to use a syntax like es2020 import here but the require('vue-calendly').default is probably the issue here.
Try importing it in the basic way as suggested above, and then you will be able to make some lazy-loading of it later on if you wish.
Also, you may use your devtools to see why your Calendly instance is not present.
Addy Osmani did a great article on how to import on interaction if you're interested into optimizing your loading time. If it's not that much needed, simply use the usual method or even simpler, load the vanilla JS solution.

Related

Can i use multiple Vue Composable functions in one file? how do I structure it?

Can i use multiple vue composables in one file?
example:
<script>
export function arrayToInt(arr) {
...
}
export function arrayToUint(arr) {
...
}
</script>
then somewhere else:
import {arrayToInt, arrayToUint} from "./useBytesHelper"
because im getting a vue router parsing error right at the beggining when loading my app. and i might be doing this wrong
Considering that the file is JavaScript module (useBytesHelper.js) and not Vue SFC (useBytesHelper.vue), it's incorrect to use <script> tag there.
The rest is correct, it should be used as listed:
import {arrayToInt, arrayToUint} from "./useBytesHelper"

Nuxt.js vuex store not persisted

I've got some strange issues with my Nuxt.js Setup.
Some States in Store arent persistent, everytime I load another view, they went back to the default value.
pages/test.vue
<template>
<section class="section">
<b-container>
<b-row>
<b-col cols=12>
<b-button #click="setTest" variant="dark">test</b-button> | {{this.$store.state.test}} |
</b-col>
</b-row>
</b-container>
</section>
</template>
<script>
export default {
name: 'test',
methods: {
setTest() {
this.$store.commit("setTest")
},
}
}
</script>
store/index.js
export const state = () => ({
test: "test"
})
export const mutations = {
setTest: (state) => state.test = 'Hello'
}
Testscenario is to hit the "test"-button who call the method with mutation-commit "setTest" which set the state to "Hello". Currently it works fine, but if I changed the view or reload the page, the state is set to default "test".
What am I doing wrong?
Alright, so the behavior is totally logic. Vuex/Pinia are not supposed to be persistent.
For any persistence on the front-end, you need either:
cookies
localStorage
pass it in the URL (query params)
IndexedDB
get the data back from making a call to a backend
If you are using Vuex or Pinia, there are also packages that you could use to get an easier time (to sync your store into something persistent automatically).
Some of the packages here may be useful: https://github.com/vuejs/awesome-vue#persistence
For pinia: https://stackoverflow.com/a/73863929/8816585
If you reload your page with an F5, all your JS will be wiped and loaded again. Hence, no state will be kept since it will be a brand new page. When working with frontend frameworks, you cannot expect it to just work after a page refresh.
Same go when you do follow an href, it is an actual real navigation. What you need to do, is to use a <nuxt-link></nuxt-link> component, with something like to="/profile" to let VueJS move to this URL.
NuxtLink is a Nuxt.js component and essentially a component on top of <router-link></router-link>, which is Vue router.
TLDR: you cannot use things like window.location.href, nor <a href="...". You may use the given components by either Nuxt (nuxt-link) or Vue's router (router-link), if you're using VueJS only.
Giving a read to the Vue router's documentation may be a good start to understand things a bit more !
If you're using nuxt/auth, give a try to that one: https://auth.nuxtjs.org/api/storage/#universal-storage

Can't build Gridsome website with Vue2 Smooth Scroll

It works in develop mode but it does not build: 'ReferenceError: window is not defined'
I do understand it is a problem with SSR support, although it says it has support to it
I have tryed to implement some similar approaches of integration as seen here:
https://gridsome.org/docs/assets-scripts/#without-ssr-support
Import Vue-Navigation-Bar in Gridsome
I've tryed a lot of approaches in main.js and my template.vue files, but I'm failing to understand the logic for adapting the solution perfectly.
My last approach which worked on develop:
On my template.vue file:
<section id="cover"></section>
<ClientOnly><p class="text-light">Text <a :href="href" class="text-light under" v-smooth-scroll="{ duration: 1000, updateHistory: false }">click here</a></p></ClientOnly>
<script>
import Vue from 'vue'
import vueSmoothScroll from 'vue2-smooth-scroll'
Vue.use(vueSmoothScroll)
</script>
Also have tryed to set 'container' option to '#app' or '#body' added to the body, but it didn't work not even in develop.
OK, I could find it here:
https://github.com/gridsome/gridsome/issues/180#issuecomment-513550238
It doesn't need <ClientOnly></ClienteOnly> tags in template.vue file
In main.js, I have made this changes:
//import vueSmoothScroll from 'vue2-smooth-scroll'
//Vue.use(vueSmoothScroll);
export default function (Vue, { router, head, isClient }) {
...
if (process.isClient) {
const vueSmoothScroll = require('vue2-smooth-scroll').default;
Vue.use(vueSmoothScroll);
}
}

How can I turn off SSR for only certain pages in Nuxt.js to use them as SPA application?

I want to develop an application with Nuxt.js that uses SSR for only certain pages (like artist page user page), so the pages without SSR will be used like an SPA. Is it possible to do it using Nuxt.js?
You could do that via server middleware. Add following file under ~/server-middleware/check-spa.js, for example. Do not use middleware directory as it is for route middleware and gets copied to the client code.
export default function(req, res, next) {
const paths = ['/', '/a']
if (paths.includes(req.originalUrl)) {
// Will trigger the "traditional SPA mode"
res.spa = true
}
// Don't forget to call next in all cases!
// Otherwise, your app will be stuck forever :|
next()
}
Then, in nuxt.config.js enable serverMiddleware like this
serverMiddleware: ['~/server-middleware/check-spa']
More info here: https://nuxtjs.org/docs/configuration-glossary/configuration-servermiddleware/
https://blog.lichter.io/posts/nuxt-dynamic-ssr-spa-handling/
Wrap the contents of the component you don't want to render server side in a <client-only></client-only> tag (<no-ssr></no-ssr> for nuxt version < 2.9.0).
#DenisTsoi's link should give you more information on how it works.
If your Nuxt version >v2.9.0, then use <client-only> instead of <no-ssr>.
Here is an example:
<template>
<div>
<sidebar />
<client-only placeholder="Loading...">
<!-- this component will only be rendered on client-side -->
<comments />
</client-only>
</div>
</template>
The Loading... is used as a placeholder until the component(s) within <client-only> is mounted on client-side.
You can learn more about this here: Nuxt API - The <client-only> Component
If it is a component that is inserted in another component, wrap it in <no-ssr> <your-component /> </no-ssr> tags. (it used to be <client-only> </client-only>)
If it is a plugin or a mixin which is inserted in nuxt.connfig file, you can change it to
plugins:[
{ src: your-plugin, ssr: false }
]
Just go to your nuxt.config.js, search for mode and change it fro

Unknown html tag warning of Bootstrap-Vue.js support in WebStorm

I'm using WebStorm 2017.2.4 and webpack Vue.js project. I have added bootstrap-vue.js to my project and would like to see hints for it and components support.
But instead of that I have got "Unknown html tag" warning.
BTW: bootstrap-vue works as expected when running project.
Do you have any suggestions how to make it work?
UPDATED on 2019/07/30
PHPShtorm(WebStorm) was updated to 2019.2 and now they added better support for vuejs libraries:
https://blog.jetbrains.com/webstorm/2019/07/webstorm-2019-2/#development_with_vue
I've just tested and it works.
OLD answer
I solved this issue by adding components manually.
According to: https://bootstrap-vue.js.org/docs/#individual-components-and-directives
I created new file, e.g. bootstrap.js then register globally components which required
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import Vue from 'vue';
import navbar from 'bootstrap-vue/es/components/navbar/navbar';
import container from 'bootstrap-vue/es/components/layout/container';
// ...
Vue.component('b-navbar', navbar);
Vue.component('b-container', container);
// ...
It work for me in phpstorm 2018.1
Bootstrap vue uses very dynamic way of defining components. I am using PyCharm with vuejs extension which is unable to resolve the components when registered using
import { Layout } from 'bootstrap-vue/es/components'
Vue.use(Layout)
What I use to do is make a new file bootstrap.js in components directory, and register all bootstrap components I would use like
import Vue from 'vue'
import bContainer from 'bootstrap-vue/es/components/layout/container'
import bRow from 'bootstrap-vue/es/components/layout/row'
import bCol from 'bootstrap-vue/es/components/layout/col'
Vue.component('b-container', bContainer);
Vue.component('b-col', bCol);
Vue.component('b-row', bRow);
and then import this file in main.js
import './components/bootstrap'
Just a little cleaner solution.
#Updated: There're two ways to fix "Unknown html tag" warning: (Global and Local Registration)
Global Registration :
You should have to register your component globally Vue.component(tagName, options) before creating the new Vue instance. For example:
Vue.component('my-component', {
// options
})
Once registered, a component can be used in an instance’s template as a custom element, <my-component></my-component>. Make sure the component is registered before you instantiate the root Vue instance. Here’s the full example:
HTML:
<div id="example">
<my-component></my-component>
</div>
JS:
// global register
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
el: '#example'
})
Which will render HTML::
<div id="example">
<div>A custom component!</div>
</div>
Local Registration :
You don’t have to register every component globally. You can make a component available only in the scope of another instance/component by registering it with the components instance option:
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> will only be available in parent's template
'my-component': Child
}
})
The same encapsulation applies for other registerable Vue features, such as directives.
Read more at https://v2.vuejs.org/v2/guide/components.html#Using-Components
#Before Updated:
In WebStorm, a library is a file or a set of files whose functions and methods are added to WebStorm's internal knowledge in addition to the functions and methods that WebStorm retrieves from the project code that you edit. In the scope of a project, its libraries by default are write-protected.
WebStorm uses libraries only to enhance coding assistance (that is, code completion, syntax highlighting, navigation, and documentation lookup). Please note that a library is not a way to manage your project dependencies.
Source: https://www.jetbrains.com/help/webstorm/configuring-javascript-libraries.html
Simply, upgrade WebStorm from version 2017.2.4 to 2017.3 which fixed this issue. It is tested.