seo component gatsby- effecting layout - seo

having this very bizarre problem with my gatsby project where the SEO component (quite similar to the default on suggested in docs) is effecting my page layout. no matter where i put the SEO component (inside or outside the layout wrapper component my navbar seems to be effected... very strange because the seo component from what i can see has no stylings or jsx or css or anything. its just a way to add meta tags for SEO.. can someone help? here is my page layout (using basic react context and seo compoennt here to inject meta deatail)
<NavActive.Provider value={active}>
<SEO image={logo} />
<Layout active={active} setActive={setActive}>
<div className={`${active&&'body-active'}`}>
<Banner />
<Column />
<Paragraph text={text} header/>
<Blackbar />
<Paragraph text={text} />
<Blackbar button />
<Split />
<div className='c'>
<Blackbar />
</div>
</div>
</Layout>
</NavActive.Provider>
and then here is the way my seo compoennts is structured. have NO idea what could be causing this!
/**
* SEO component that queries for data with
* Gatsby's useStaticQuery React hook
*
* See: https://www.gatsbyjs.org/docs/use-static-query/
*/
import React from "react"
import PropTypes from "prop-types"
import { Helmet } from "react-helmet"
import { useLocation } from "#reach/router"
import { useStaticQuery, graphql } from "gatsby"
function SEO({ description, lang, meta, image, title }) {
const { pathname } = useLocation()
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
author
image
url
}
}
}
`
)
const seo = {
title: title || "Orcawise - Start a willing conversation",
description: site.siteMetadata.description,
image: image || `${site.siteMetadata.url}${site.siteMetadata.image}`,
url: `${site.siteMetadata.url}${pathname}`,
}
return (
<>
<Helmet>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
{/* <meta property="og:image" content={seo.image} />
<meta property="og:url" content={seo.url} />
<meta property="twitter:image" content={seo.image} />
<meta property="og:description" content={seo.description} />
<meta name="author" content={seo.author} /> */}
</Helmet>
<Helmet
htmlAttributes={{
lang,
}}
title={seo.title}
titleTemplate={`%s | ${seo.title}`}
meta={[
{
property: `og:title`,
content: seo.title,
},
{
name: `description`,
content: seo.description,
},
{
name: `author`,
content: seo.author,
},
{
property: `og:description`,
content: seo.description,
},
{
property: `og:url`,
content: seo.url,
},
{
property: `og:image`,
content: seo.image,
},
{
property: `og:type`,
content: `website`,
},
{
name: `twitter:card`,
content: `summary_large_image`,
},
{
name: `twitter:image`,
content: seo.image,
},
{
name: `twitter:creator`,
content: seo.author,
},
{
name: `twitter:title`,
content: seo.title,
},
{
name: `twitter:description`,
content: seo.description,
},
].concat(meta)}
/>
</>
)
}
SEO.defaultProps = {
lang: `en`,
meta: [],
description: ``,
image: null,
url: ``,
}
SEO.propTypes = {
description: PropTypes.string,
lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string.isRequired,
image: PropTypes.string,
url: PropTypes.string,
}
export default SEO

very strange because the seo component from what i can see has no
stylings or jsx or css or anything. its just a way to add meta tags
for SEO.. can someone help?
Well, you are adding Bootstrap styles in:
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
Try removing/commenting it to see if it affects the layout. The rest of the component seems quite standard.

Related

Make a link list component of a link component in Vue

I've just made a Link component in Vue, which is new for me. Now I need to make a Link list component, which is basically an UL of LI elements of this Link component. I looked for a solution, but most most of the examples do work with a local array/object and I can't seem to figure it out.
So my question here is: What would a Link list component look like, making use of the existent Link component?
Here's the Link component:
<template>
<nuxt-link
:to="localePath(url)"
:class="$style.link"
>
<Icon
v-if="icon"
class="icon icon--size:2.5x"
:name="icon"
/>
<span
class="text"
>
{{ text }}
</span>
</nuxt-link>
</template>
<script src="./index.js"></script>
<style type="text/css" src="./index.module.scss" module lang="scss"></style>
import { Icon } from "#/components";
export default {
props: {
text: {
type: String,
required: true,
default: "",
},
url: {
type: String,
required: true,
default: "",
},
icon: {
type: String,
required: true,
default: "",
},
expert: {
type: Boolean,
required: false,
default: false,
},
},
components: {
Icon,
},
};
Should the Link list component receive an array as well like this?
export default {
props: {
list: {
type: Array,
required: true,
default: "",
},
},
Link,
},
};
Assuming you have an array of link objects that provide the props text, url, icon and optionally expert (because I can't see where you're using that), if your goal is to pass this array as a prop to your Link List component, then it would look something like this
<template>
<ul>
<!-- note the ":key" binding. This should uniquely identify each entry in the list -->
<li v-for="({ text, url, icon }) in list" :key="url">
<Link
:text="text"
:url="url"
:icon="icon"
/>
</li>
</ul>
</template>
<script>
import { Link } from '#/components' // or whatever makes sense
export default {
name: 'LinkList',
components: { Link },
props: {
list: Array
}
}
</script>
Using this would look something like
<template>
<LinkList :list="list" />
</template>
<script>
import { LinkList } from '#/components'
export default {
components: { LinkList },
data: () => ({
list: [{
text: 'Link #1',
url: 'https://example.com',
icon: 'whatever'
}, {
// and so on
}]
})
}
</script>

how to use code sample in ckeditor 5 vue?

i want to use the sample code feature in my ckeditor 5 vue, but i can't find it. Can anyone give me an example or how?
in my app js
...
import CKEditor from "#ckeditor/ckeditor5-vue";
Vue.use(CKEditor);
...
and my vue file
<template>
...
<ckeditor :editor="editor" v-model="CKValue" :config="editorConfig"></ckeditor>
...
</template>
<script>
import ClassicEditor from "#ckeditor/ckeditor5-build-classic";
export default {
data() {
return {
CKValue: "",
editor: ClassicEditor,
editorConfig: {}
}
},
}
</script>
You can see a sample code here
https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs.html
Like this :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CKEditor 5 – Vue.js Component – development sample</title>
<style>
body {
max-width: 800px;
margin: 20px auto;
}
textarea {
width: 100%;
height: 100px;
font-family: monospace;
}
</style>
</head>
<body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/#ckeditor/ckeditor5-build-classic/build/ckeditor.js"></script>
<script src="../dist/ckeditor.js"></script>
<div id="app">
<h1>CKEditor 5 – Vue.js Component – development sample</h1>
<ckeditor
editor="classic"
tag-name="textarea"
v-model="editorData"
:editor="editor"
:config="editorConfig"
:disabled="editorDisabled"
#ready="onEditorReady"
#focus="onEditorFocus"
#blur="onEditorBlur"
#input="onEditorInput"
#destroy="onEditorDestroy"
></ckeditor>
<button v-on:click="toggleEditorDisabled()">
{{ editorDisabled ? 'Enable' : 'Disable' }} editor
</button>
<button v-on:click="destroyApp()">Destroy the app</button>
<h2>Live editor data</h2>
<textarea v-model="editorData"></textarea>
</div>
<script>
Vue.use( CKEditor );
const app = new Vue( {
el: '#app',
data: {
editor: ClassicEditor,
editorData: '<p>Hello world!</p>',
editorConfig: { toolbar: [ 'heading', '|', 'bold', 'italic' ] },
editorDisabled: false
},
methods: {
toggleEditorDisabled() {
this.editorDisabled = !this.editorDisabled;
},
destroyApp() {
app.$destroy();
},
onEditorReady( editor ) {
console.log( 'Editor is ready.', { editor } );
},
onEditorFocus( event, editor ) {
console.log( 'Editor focused.', { event, editor } );
},
onEditorBlur( event, editor ) {
console.log( 'Editor blurred.', { event, editor } );
},
onEditorInput( data, event, editor ) {
console.log( 'Editor data input.', { event, editor, data } );
},
onEditorDestroy( editor ) {
console.log( 'Editor destroyed.', { editor } );
}
}
} );
</script>
</body>
</html>

Vue.js - How to switch the URL of an image dynamically?

I am working on a site where the user can select an image via radio selection.
I would like to dynamically update the image URL depending on selection of the user. My approach is to use a computed variable which returns the URL from a list of objects depending on the selection of the user.
<template>
<v-img
:src="require(currBackgroundURL)"
class="my-3"
contain
width="397"
height="560"
></v-img>
</template>
<script>
// data() ...
currBackground: 0,
backgrounds: [
{
name: "Flowers",
url: "../assets/background/bg_1.png"
},
// ...
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
}
</script>
Unfortunately, i get an error which says Critical dependency: the request of a dependency is an expression.
And the browser console says: [Vue warn]: Error in render: "Error: Cannot find module '../assets/background/bg_1.png'"
Question: What is the right way to switch the URL of the image dynamically?
Thanks for your help!
Here is a working example:
var app = new Vue({
el: '#app',
data: () => ({
currBackground: 0,
backgrounds: [
{
name: "black",
url: "https://dummyimage.com/600x400/000/fff"
},
{
name: "blue",
url: "https://dummyimage.com/600x400/00f/fff"
},
{
name: "red",
url: "https://dummyimage.com/600x400/f00/fff"
}
]
}),
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
},
methods: {
nextImage() {
this.currBackground += 1
if (this.currBackground > 2) {
this.currBackground = 0
}
}
}
})
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.18/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
<div id="app">
<v-btn #click="nextImage()">Change image</v-btn>
<v-img
:src="currBackgroundURL"
class="my-3"
contain
width="397"
height="560"
></v-img>
</div>
</body>
I removed the require.
The src is a link/path so you don't need require. require will try to take a path and load it into a module instead of a link/path.
Hopefully, this helps.

Dynamic Unorderlist web component generate using stencilJS

Using stenciljs dynamically generate nesting unordered <ul><li>...</li></ul> list, so i and giving input as a Obj={} i am getting some issues. Here is my code below Please help me on this...
1. index.html
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
<title>Stencil Component Starter</title>
<script src="/build/mycomponent.js"></script>
</head>
<body>
<list-component list-object='[
{title: "Point", children: [
{title: "Point"},
{title: "Point"},
{title: "Point"},
{title: "Point", children: [
{title: "Point"},
{title: "Point"},
{title: "Point"}
]}
]},
{title: "Point", children: [
{title: "Point"},
{title: "Point", children: [
{title: "Point"},
{title: "Point"},
{title: "Point"}
]},
{title: "Point"}
]},
]' > </list-component>
</body>
</html>
ISSUE:
I am passing nested object to the custom web component.
In this list.tsx file i am facing problem while passing arguments to the function buildList("?","?")...?
2. list.tsx
import { Component, Prop, State, Watch, Element } from '#stencil/core';
#Component({
tag:'list-component',
styleUrl:'./list-component.css'
})
export class ListComponent{
#State() idName: string;
#Prop() listObject: string;
#Element() flashElement: HTMLElement;
private ulContent: HTMLElement;
componentWillLoad() {
this.ulContent = this.flashElement.querySelector('.ul-content');
this.buildList(this.ulContent,this.listObject);
}
#Watch('listObject')
buildList(parentElement, listObject){
console.log(listObject);
var i, l, list, li, ul1;
if( !listObject || !listObject.length ) { return; }
ul1 = document.createElement('ul');
list = parentElement.appendChild(ul1);
for(i = 0, l = listObject.length ; i < l ; i++) {
li = document.createElement('li');
li.appendChild(document.createTextNode(listObject[i].title));
list.appendChild(li);
this.buildList(li, listObject[i].children);
}
}
render() {
return (
<div class="ul-content"></div>
);
}
}
I see two problems:
1: When Stencil calls #Watch methods it always passes the new and old values as arguments, see https://stenciljs.com/docs/properties#prop-default-values-and-validation. This means you cannot define custom arguments.
You could create an additional function which acts as the watcher and then calls buildList:
#Watch('listObject')
listObjectChanged() {
this.buildList(this.ulContent, this.listObject);
}
2: listObject is a string so you need to JSON.parse it before you can loop over it (and rewrite it so it's valid JSON). Then store that parsed list in a local variable and use it to generate the list. See https://medium.com/#gilfink/using-complex-objects-arrays-as-props-in-stencil-components-f2d54b093e85
There is a much simpler way to render that list using JSX instead of manually creating the list elements:
import { Component, Prop, State, Watch, Element } from '#stencil/core';
#Component({
tag: 'list-component',
styleUrl: './list-component.css'
})
export class ListComponent {
#Element() flashElement: HTMLElement;
#State() idName: string;
#Prop() listObject: string;
#State() list: any[];
#Watch('listObject')
listObjectChanged() {
this.list = JSON.parse(this.listObject);
}
componentWillLoad() {
this.listObjectChanged();
}
renderList(list) {
return list.map(list => <ul>
<li>{list.title}</li>
{list.children && this.renderList(list.children)}
</ul>
);
}
render() {
return (
<div class="ul-content">
{this.renderList(this.list)}
</div>
);
}
}
Hope this helps.

Vue js 2 hide shared component

<template>
<div id="app" class="phone-viewport">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<router-view></router-view>
<bottomBar v-bind:visibles='show' ></bottomBar>
</div>
</template>
<script>
export default {
name: '',
show: '',
data () {
return {
visibles: [
{name: 'Football', show: true},
{name: 'Basketball', show: true},
{name: 'Hockey', show: true},
{name: 'VolleyBall', show: false},
{name: 'Baseball', show: false},
]
}
}
}
</script>
I'm looking to hide the bottomBar just on VolleyBall and Beisbol .
But I always have this error "Property or method "show" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
"
<script>
export default {
name: 'app',
data () {
return {}
},
computed: {
hideBottom: function () {
if (this.$router.path === '/baseball' || this.$router.path === '/volleyball') return false
else { return true }
}
}
}
Baseball
You are calling method show which does not exist, that's why you are getting that error.
As I understand your question, you want to hide that component on particular routes?
If so, You need to create computed variable which will determine if it should be shown or not. e.g.:
computed: {
toShowOrNotToShow: function () {
if(this.$router.path === '/baseball' || this.$router.path === '/volleyball') return false;
else
return true;
}
}
Just use it: <bottomBar v-if='toShowOrNotToShow' ></bottomBar>