Gatsby Background Images & WPGraphQL for Advanced Custom Fields - wordpress

I am trying to set a background in Gatsby using gatsby-background-image plugin.
My query returns sourceUrl and alt-text just fine. However, when running gatsby develop it gives me an error "TypeError: Cannot read property 'hero' of undefined". Doing some research I think I might have to use ChildImageSharp to specify fluid. However, I am not really sure if that is possible for an ACF field?
import React from "react"
import BackgroundImage from "gatsby-background-image"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
const IndexPage = (props) => (
<Layout>
<SEO title="Home" />
<BackgroundImage
className="masthead"
fadeIn
fluid={props.data.wordpress.pages.nodes.undersideACFgraphql.hero.sourceUrl}
>
<div className="black-overlay">
<div className="content-box">
<h1>This is where my h1 tag goes</h1>
<h2>This is my sub head</h2>
</div>
</div>
</BackgroundImage>
<Link to="/page-2/">Go to page 2</Link>
</Layout>
)
export default IndexPage
export const pageQuery = graphql`
query MyQuery {
wordpress {
pages {
nodes {
undersideACFgraphql {
hero {
sourceUrl
altText
}
}
}
}
}
}
`;

Related

Images not showing after adding const slider ... so confused

So i've been following a tutorial and trying to teach myself next.js with lazy loading slider and tailwindcss.. I am a beginner but i have made ecommerce sites and stuff to teach myself.. but this tutorial was going great until this!but Ive tried everything i know and googled it every which way to try to fix this issue!! My images were showing perfectly before i added the - const setCurrent up to the if !Array
if i delete that the images show back up... im so confused ive gone through everything - also the "Gallery" even disapeared once i added that section
and i put it all on github incase someone can look at it to help me?? https://github.com/Jessica19882/firebird
i have deleted the
const current up to the !Array part and images showed back up i have tried rewriting it as another post said but that didnt work ive checked and zoomed into the video tutorial to make sure everything was right and it is... i have checked all the other pages index.js app.js and stuff to make sure i had it just like his and it is!!
slider.js
import { SliderData } from './SliderData'
import React, { useState } from 'react'
import Image from 'next/image'
const Slider = ({ slides }) => {
const [current, setCurrent] = useState(0)
const length = slides?.length
const nextSlide = () => {
setCurrent(current === length - 1 ? 0 : current + 1)
}
const prevSlide = () => {
setCurrent(current === 0 ? length - 1 : current - 1)
}
if (!Array.isArray(slides) || slides.length <= 0) {
return null
}
return (
<div id='gallery'>
<h1>Gallery</h1>
<div>
{SliderData.map((slide, index) => {
return (
<div
key={index}
className={
index === current
? 'opacity-[1] ease-in duration-1000'
: 'opacity-0'
}>
<Image
src={slide.image}
alt='/'
width='1440'
height='600'
style={{ objectFit: 'cover' }}
/>
</div>
)
})}
</div>
</div>
)
}
export default Slider
index.js
import Head from 'next/head'
import Hero from '../components/Hero'
import Slider from '../components/Slider'
import SliderData from '../components/SliderData'
export default function Home() {
return (
<div>
<Head>
<title>Firebird Sounds</title>
<meta name='description' content='firebird sounds' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<link rel='icon' href='/favicon.ico' />
</Head>
<Hero
heading='Firebird Sounds - Audio & Video Distribution'
message='Audio and Video Distribution with a menu of
Services: Marketing, PR, Global rights management and creativity'
/>
<Slider Slides={SliderData} />
</div>
)
}
SliderData.js
export const SliderData = [
{
image:
'https://images.unsplash.com/photo-1466428996289-fb355538da1b?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTl8fG11c2ljJTIwZGlzdHJpYnV0aW9ufGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60',
},
{
image: '/images/FirebirdSounds.jpg',
},
{
image:
'https://images.unsplash.com/photo-1460667262436-cf19894f4774?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NjZ8fG11c2ljJTIwZGlzdHJpYnV0aW9ufGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60',
},
{
image: '/images/guitar.jpg',
},
{
image: '/images/firebird.png',
},
]
app.js
import Navbar from '../components/Navbar'
import '../styles/globals.css'
export default function App({ Component, pageProps }) {
return (
<>
<Navbar />
<Component {...pageProps} />
</>
)
}
https://www.youtube.com/watch?fbclid=IwAR2jl5qYoIsaFZQ26MumbFcCYv5t3eYxcqVKgm4xAsxilhEkAzSNoUB0fzE&v=HVyct9EUNP8&feature=youtu.be
I figured it out I needed to put the
Slider slides={SliderData}/>
into _app.js not index.js or both but its working again!

having issues using face detection API from Clarifai API

I have added the face detection API from Clarifai APi to my project, however, whenever i copy an image to my project and click on detects, it actually shows the image but it is not detecting the face.
see below App.js and FaceRecognition.js
import React, {Component} from 'react';
import Clarifai from 'clarifai';
import Navigation from './components/Navigation/Navigation';
import Logo from './components/Logo/Logo';
import ImageLinkForm from './components/ImageLinkForm/ImageLinkForm';
import FaceRecognition from './components/FaceRecognition/FaceRecognition';
import Rank from './components/Rank/Rank';
import './App.css';
const app = new Clarifai.App({
apiKey: 'xxxxxxxxxxxx'
});
class App extends Component {
constructor() {
super();
this.state = {
input: '',
imageUrl: '',
box: {}
}
}
calculateFaceLocation =(data) => {
const clarifaiFace = data.outputs[0].data.regions[0].region_info.bounding_box;
const image = document.getElementById('inputimage');
const width = Number(image.width);
const height = Number(image.height);
return {
leftCol: clarifaiFace.left_col * width,
topRow: clarifaiFace.top_row * height,
rightCol: width - (clarifaiFace.right_col * width),
bottomRow: height - (clarifaiFace.bottom_row * height)
}
}
displayFaceBox = (box) => {
console.log(box)
this.setState({box: box});
}
onInputChange = (event) => {
this.setState({input: event.target.value})
}
onButtonSubmit = () => {
this.setState({imageUrl: this.state.input})
app.models.predict(
Clarifai.FACE_DETECT_MODEL,
this.state.input)
.then( response => this.displayFaceBox(this.calculateFaceLocation(response)))
.catch(err => console.log(err));
}
render() {
return (
<div className="App">
<Navigation />
<Logo />
<Rank />
<ImageLinkForm
onInputChange={this.onInputChange}
onButtonSubmit={this.onButtonSubmit} />
<FaceRecognition box={this.state.box} imageUrl={this.state.imageUrl}/>
</div>
);
}
}
export default App;
FaceRecognition.js
import React from 'react';
import './FaceRecognition.css';
const FaceRecognition = ({imageUrl, box}) => {
return (
<div className='center ma'>
<div className='absolute mt2'>
<img id='inputimage' alt='' src={imageUrl} width='500px' height='auto' />
<div className='bounding-box' style=
{{top: box.topRow, right: box.rightCol, bottom: box.bottomRow, left: box.leftCol}}></div>
</div>
</div>
);
}
export default FaceRecognition;
FaceRecognition.css
bounding-box {
position: absolute;
box-shadow: 0 0 0 3px #149df2 inset;
display: flex;
flex-wrap: wrap;
justify-content: center;
cursor: pointer;
}
what am i doing wrong?
i tried copy paste from the actual Clarifai API code, but no luck
the bounding-box css is not even showing up in the console.
please help me
First of all, please don't use this client: https://github.com/Clarifai/clarifai-javascript, it has been deprecated for a while and several things in this package are very old and broken.
If you're purely developing client-side, you can use the REST endpoints directly: https://docs.clarifai.com/api-guide/predict/images (see "Javascript (REST)" snippets throughout the docs)
I also recommend to use PAT instead of API keys. This will allow you access across all your Clarifai apps with a single token.
Clarifai has changed the way to use their Api. On Clarifai Face detect model , click to use model, then you can copy the code on how to use their Api.
https://clarifai.com/clarifai/main/models/face-detection?utm_source=clarifai&utm_medium=referral&tab=versions
Then you can import your PAT and other credentials requested for in the code from Clarifai portal.
Use this as a guide https://help.clarifai.com/hc/en-us/articles/4408131744407-Integrating-Clarifai-in-your-React-Javascript-project
You are welcome 🤗

Theme with React and Redux

i am trying to make a theme system on a react project that uses redux with a reducer that manages themes according to the user's local storage. But here my problem is that I used css files to define my styles on all of my components. However, I have all my logic with 2 javascript objects for light or dark mode. So I can't use js in css files unless I use css variables but I don't know how.
Here is my structure :
In my app.js I imported useSelector and useDispatch from react redux to access the global state :
import React from 'react';
import './App.css';
import Footer from './components/Footer';
import Header from './components/Header';
import Presentation from './components/Presentation';
import Projects from './components/Projects';
import Skills from './components/Skills';
import Timeline from './components/Timeline';
import { switchTheme } from './redux/themeActions';
import { useSelector, useDispatch } from 'react-redux';
import { lightTheme, darkTheme } from './redux/Themes';
function App() {
const theme = useSelector(state => state.themeReducer.theme);
const dispatch = useDispatch();
return (
<div className="App">
<Header />
<input type='checkbox' checked={theme.mode === 'light' ? true : false}
onChange={
() => {
if(theme.mode === 'light') {
dispatch(switchTheme(darkTheme))
} else {
dispatch(switchTheme(lightTheme))
}
}} />
<div className="top">
<div className="leftPart">
<Presentation />
<Skills />
</div>
<Timeline />
</div>
<Projects />
<Footer />
</div>
);
}
export default App;
and in themes.js I have my 2 objects which represent the themes :
export const darkTheme = {
mode: 'dark',
PRIMARY_BACKGROUND_COLOR: '#171933',
SECONDARY_BACKGROUND_COLOR: '#1e2144',
TERTIARY_BACKGROUND_COLOR: '#0a0c29',
PRIMARY_TEXT_COLOR: '#eee',
SECONDARY_TEXT_COLOR: '#ccc',
PRIMARY_BORDER_COLOR: '#aaa'
}
export const lightTheme = {
mode: 'light',
PRIMARY_BACKGROUND_COLOR: '#D3CEC8',
SECONDARY_BACKGROUND_COLOR: '#E5DFD9',
TERTIARY_BACKGROUND_COLOR: '#C1BFBC',
PRIMARY_TEXT_COLOR: '#222',
SECONDARY_TEXT_COLOR: '#333',
PRIMARY_BORDER_COLOR: '#555'
}
You can make use of data attributes.
I have done the same in one my project like so :-
[data-color-mode="light"] {
--color-focus-ring: #7daee2;
--color-link-hover: #0039bd;
--color-primary-bg: #eef6ff;
--color-primary-text: #212121;
--color-primary-border: #98b2c9;
--color-secondary-bg: #c3d7f0;
--color-secondary-text: #1a1a1a;
}
[data-color-mode="dark"] {
--color-focus-ring: #5355d4;
--color-link-hover: #4183c4;
--color-primary-bg: #080808;
--color-primary-text: #f1f1f1;
--color-primary-border: #525252;
--color-secondary-bg: #191919;
--color-secondary-text: #d8d5d5;
}
You can add the attribute to your top-level element (assuming div) like so:-
<div className="appContainer" data-color-mode="light" ref={appRef}> ></div>
Now use that appRef to change the data-color-mode attribute as well update the localstorage in one function. Updating the data-color-mode allows you to toggle between css variable colors easily. In my code, I have done this the following way:-
const toggleColorMode = () => {
const nextMode = mode === "light" ? "dark" : "light";
// container is appRef.current only
container?.setAttribute("data-color-mode", nextMode);
setMode(nextMode);
};
I am not using redux for this. Simply React Context API is being used by me but it's doable in your scenario as well.
You can take more reference from the repo - https://github.com/lapstjup/animeccha/tree/main/src
Note - I think there are other routes where people go with CSS-IN-JS but I haven't explored them yet. This solution is one of the pure css ways.
Fun fact - Github has implemented their newest dark mode in a similar way and that's where I got the idea as well. You can inspect their page to see the same attribute name :D.

NextJS dynamic title

Have been googling forever and found a way to change the <title>. That way is this: https://github.com/zeit/next.js/tree/master/examples/layout-component
The main problem with this is that everytime someone refresh the site/change page the title goes from http://localhost:3000 to the actual Title (eg. About us) and I'm a bit afraid of how this is affecting the SEO.
What is the correct way of chaning the page title dynamically?
My layout file:
import Link from 'next/link'
import Head from './../node_modules/next/head'
export default function Layout({ children, title = 'Welcome to my website' }) {
return (
<div>
<Head>
<title>{title}</title>
</Head>
{children}
</div>
)
}
Check out next-seo and install it in your next.js application.
yarn add next-seo
# or
npm install --save next-seo
And it will handle the page title and the meta description for you magically.
import React from 'react';
import { NextSeo } from 'next-seo'; // then add the `NextSeo` at any `pages/` that you wish
export default () => (
<>
<NextSeo
title="About Us, or just any title that you wish"
description="Then with a short description here."
/>
<p>Simple Usage</p>
</>
);
I have implemented the same tactic on my own web app here.
Well for me this works,
Import <Head> from next,
import Head from 'next/head'
And in return statement,
<>
<Head>
<title>Page Title</title>
</Head>
<section>
<Your_JSX_CODE>
</section>
</>
If you need a dynamic title/description, for example for the route parameters case, you can do this. (Consider that the page name is [id].js)
import React from 'react'
import { NextSeo } from 'next-seo' //as proposed by #xun
// import Head from "next/head" //alternative solution
const Detail = ({id}) => {
const title = `My ${id} title.`
const description = `My ${id} description.`
return (
<>
<NextSeo
title={title}
description={description}
/>
<p>It works!</p>
</>
)}
export default Detail
And at the end of your file:
export async function getServerSideProps({query}) {
const { id } = query
return {
props: {
id
},
};
}
Good luck!
I reninstalled "next" and "next-routes" in my dependencies and now this works.

Cant overwrite the custom stylesheet

I am trying to overwrite the CSS of react range slider.It uses the custom style sheet of which i need to add in the head section.My project is built on next.js
<link rel="stylesheet" href="https://unpkg.com/react-rangeslider/umd/rangeslider.min.css" />
Otherwise, the slider doesn't show anything if i don't add the link in head even though I installed the library. It's not even overwriting the CSS. I want to change the background color.This is my code:
import React, { Component } from 'react'
import 'react-rangeslider/lib/index.css';
import './slider.css';
import Slider from 'react-rangeslider'
class Horizontal extends Component {
constructor (props, context) {
super(props, context)
this.state = {
value: 850
}
}
handleChangeStart = () => {
console.log('Change event started')
};
handleChange = value => {
this.setState({
value: value
})
};
handleChangeComplete = () => {
console.log('Change event completed')
};
render () {
const { value } = this.state
return (
<div>
<div className='slider' style={{ marginTop:'165px',marginLeft:'319px',width:'700px',backgroundColor:'EF5350'}} >
<div style={{ textAlign:'center',color:'gray',fontSize:'35px',marginBottom:'82px'}}>
<p> What is the size of your property?</p>
</div>
<Slider
min={850}
max={5000}
value={value}
onChangeStart={this.handleChangeStart}
onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete}
/>
<div className='value'>{value}</div>
</div>
</div>
)
}
}
export default Horizontal
I tried to change the background color in slider.css.
.rangeslider-horizontal .rangeslider__fill {
background-color: red;
}
The library needs to be installed first:
npm install react-rangeslider --save
It doesn't work as the slider stylesheet overwrite yours. Include the style like
// To include the default styles
import 'react-rangeslider/lib/index.css'
// import your css
import './style.css';
Demo
always make your own CSS stylesheet file the last file to import after any other CSS stylesheet files to make overwrite you need
otherwise, you can always use the console in the browser to auto-detect any error by pressing F12 in the browser then go to the tab called (console)
I think you can style element you want to live in the console to know the detail of how to nesting element
you also can open the CSS file in the editor and press Ctrl+F then find the line of code you want to style then copy its property and value to your own CSS file and then you can edit it so easy

Resources