Storing Gatsby page content - reactjs

I'm exploring Gatsby to make a static website with multiple pages. Those pages will have the same template, just the text will change. To make it easier, I'm going to create a single template. I want to store the content of the different pages (text, path etc.)in Yaml or JSON file. So basically it would look like this :
import React from "react";
import content from '../content/pageContent.yaml'
const Template = () => {
return (
<header className="div1">
<div className="flex items-center justify-center container mx-auto">
<div className="basis-1/2 el tagline">
<h1>{content.title}</h1>
<p>{content.description}</p>
<button>Lets go</button>
</div>
<div className="basis-1/2 el">
<img src=`../images/${pic}`
</div>
</div>
</header>
...
)
}
export template
Here is my pageContent.yaml
title: YAML content used at build time with Gatsby
description: my description with a <b>bold word</b>
pic: mypicture.png
Everything works great but the problem is that it doesn't render the HTML tags. But if I use <h1 dangerouslySetInnerHTML={ {__html: content.titre} }></h1> instead of <h1>{content.title}</h1> it renders the HTML tag.
My question is : is it ok to make it this way? Would it be a better way to do that ?
Thanks a lot

dangerouslySetInnerHTML exposes your app to security risks such as Cross-site scripting XSS attacks.
You could use a library like react-markdown to convert the markdown to html.
Here is an example of how you could do it, adapt as appropriate.
import React from "react";
import content from '../content/pageContent.yaml'
import ReactMarkdown from "react-markdown";
const Template = () => {
return (
<header className="div1">
<div className="flex items-center justify-center container mx-auto">
<div className="basis-1/2 el tagline">
<ReactMarkdown source={content.title} />
<ReactMarkdown source={content.description} />
<button>Lets go</button>
</div>
<div className="basis-1/2 el">
<img src=`../images/${pic}`
</div>
</div>
</header>
...
)
}
export template

Related

How to properly import images and videos in Next js

I just want to ask how to properly import images and videos in nextjs? My images doesn't load on nested route page, like this -> localhost:3000/about/missionVision It works on single path though, like this -> localhost:3000/about
This is the code of the component with image that doesn't load on nested route/page.
import React, { Fragment } from "react";
const Banner= () => {
return(
<Fragment>
<header className="banner">
<div className="container">
<div className="logo">
<img src="./images/logo.png" alt="our logo"/>
</div>
</div>
</header>
</Fragment>
)
}
export default Banner;
I used to use this format of importing, but there's always an error when I imported videos/mp4 files, plus image doesn't show. ( I migrated cra to next)
import React, { Fragment } from "react";
import logo from "./../../public/images/logo.png";
const Banner= () => {
return(
<Fragment>
<header className="banner">
<div className="container">
<div className="logo">
<img src={ logo }/>
</div>
</div>
</header>
</Fragment>
)
}
export default Banner;
This is my file structure
root folder
components
Banner
-index.js
page
public
images
videos
Thank you!
Edit: This is the error that shows whenever I try to import a video.
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See
https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
No Need for import public path just try to access from the public path.
<img src={"/images/xyz.svg"} />

Working with images local files in Gatsby.js

I am trying to render a headshot for each artist displayed on the page. The artist data comes from a Json file, and the images are located in images/artists/headshots. I am using the regular img tag, but for some reason nothing is displaying on the page. Any help any one can give would be greatly appreciated.
import React from 'react'
import PropTypes from 'prop-types'
import { StaticImage } from 'gatsby-plugin-image'
import { useStyles } from './styles'
const ArtistsPage = ({ data }) => {
const classes = useStyles()
return (
<section>
<article className={classes.artistsBackground}>
<div className={classes.heroLayoutContainer}>
<h3 className={classes.title}>MEET THE ARTISTS</h3>
<StaticImage
className={classes.heroImage}
src='../../images/artists/hero-images/hero-image-artists.jpg'
alt='hero-image-artists'
placeholder='blurred'
/>
</div>
</article>
<article className={classes.artistsContainer}>
<div className={classes.flexContainer}>
{data.allArtistsJson.edges
.map(({ node }, idx) => {
const artist = `${node.firstName}+${node.lastName}`
.split('+')
.join(' ')
return (
<div className={classes.flexItem} key={idx}>
<div>
<img
src={`../../images/artists/headshots/${artist} Headshot.jpg`}
alt='artist-headshot'
/>
</div>
<div className={classes.artistCardName}>
{`${node.firstName} ${node.lastName}`.toUpperCase()}
</div>
<div className={classes.artistCardText}>{node.city}</div>
<div className={classes.artistCardText}>
{node.currentTeam}
</div>
</div>
)
})}
</div>
</article>
</section>
)
}
export default ArtistsPage
My image files are set up as:
FirstName LastName Headshots.jpg
I think your issue may comes from the white spaces in the naming. Your code looks good at first sight so try renaming your images with underscore or in camelCase:
<img
src={`../../images/artists/headshots/${artist}_Headshot.jpg`}
alt='artist-headshot'
/>
After much research and the nice people on Gatsby discord I found the answer to be… in a scenario like this I needed to add require().default.
Ex:
<img
src={require(../../images/artists/headshots/${artist} Headshot.jpg).default}
alt='artist-headshot'
/>

Why won't my React website display images?

I have a JS file; Cards.js which implements a card-style div:
import React from "react";
import CardItem from "./CardItem";
import "./Cards.css";
function Cards() {
return (
<div classNam="cards">
<ul className="cards__items">
<CardItem
src={require("../images/img-9.jpg").default}
text="text"
label="label"
path="/jobs"
/>
</ul>
</div>
);
}
export default Cards;
And then CardItem.js:
import React from "react";
import { Link } from "react-router-dom";
function CardItem(props) {
return (
<div>
<li className="cards__item">
<Link className="cards__item__link" to={props.path}>
<figure className="cards__item__pic-wrap"
data-category={props.label}>
<img
src={props.src}
className="card__item__img"
alt="alt"
/>
</figure>
<div className="cards__item__info">
<h5 className="cards__item__text">{props.text} </h5>
</div>
</Link>
</li>
</div>
);
}
export default CardItem;
However, on my site, the images from CardItem are not displayed. The Text, Label and Path all work, but no image.
I've looked around and have seen different solutions to this issue but none have worked for me.
I've tried using
src="../images/img-9.jpg"
instead of using require but that also didn't work.
What's weird is I can see the path AND the preview of the image when looking at the Chrome inspection panel, but they won't load.
I've also tried putting the images folder in the Public directory which is another solution I've seen, but I get an error saying something about loading resources outside of /src

Background doesn't resize in responsive tailwindcss

I'm busing tailwindcss for my css. So for this I defined the image inside the tailwind config. Then I applied a cover on it but the image doesn't scale when I change the size of the screen. I thought by adding max-w-full min-h-full would fixe the problem but nothing.
import React from 'react'
import { CountdownEvent } from './CountdownEvent'
import { CarouselSaf } from './CarouselSaf'
import { Navbar } from './Navbar'
export const Home = () => {
return (
<section className="h-screen">
<div className="bg-safthon bg-no-repeat bg-cover max-w-full min-h-full">
<Navbar />
<div className="flex h-screen items-center">
<CountdownEvent />
</div>
</div>
</section>
)
}
Try to keep it simple. Check this demo.
<div class="min-h-screen max-h-screen bg-cover bg-center bg-no-repeat"
style="background-image: url('https://i.ytimg.com/vi/odM92ap8_c0/maxresdefault.jpg')">
</div>

Attempting to embed AWS Lex chatbot into React site, failing with Error: Missing credentials in config (see console for details)

I am comfortable with many aspects of AWS, but not with Cognito. I have built Lex style chatbots as Alexa skills, but this is my first time attemtping to integrate a Lex chatbot into an existing website. The website is coded in React.js using www.codesandbox.io as I'm just learning React. I'm comfortable with C#, but React is new for me. If some of the code below doesn't seem to do much, it's just because I"m testing different components, functions versus classes etc. Anyway, I've built a simple chatbot in Lex and have attempted to integrate it into this React site, but am getting the error - Error: Missing credentials in config (see console for details) whenever I attempt to chat with the bot. Any ideas? I'm not sure what I"m doing wrong.
import React from "react";
import ReactDOM from "react-dom";
import bootstrap from "bootstrap"; // eslint-disable-line no-unused-vars
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import "./styles.css";
import LexChat from "react-lex";
import AWS from 'aws-sdk';
AWS.config.update({
region: "us-west-2",
credentials: new AWS.CognitoIdentityCredentials({
IdentityPoolId: "us-west-2:<redacted>"
})
});
class CDataRow extends React.Component {
render() {
return (
<h1>
Name:{this.props.myname}
<br />
Email:{this.props.email}
</h1>
);
}
}
const TitleCard = props => (
<div class="container">
<div class="media">
<span class="media-left">
<img
src="https://content.mactores.com/2017/05/19105931/Amazon-Rekognition.png"
alt="..."
/>
</span>
<div class="media-body">
<h3 class="media-heading">
{props.titleheading} <h5>{props.subtitle}</h5>
</h3>
</div>
</div>
</div>
);
const Datarow = props => (
<div>
<b>Name:{props.myname}</b>
<br />
<b>Email:{props.email}</b>
</div>
);
const Layout = props => (
<div>
<header>Super Header of Document</header>
<main>{props.children}</main>
<footer>Super Footer Copyright mystuff 2018 (C)</footer>
</div>
);
const DomainOutside = props => (
<div>
<div class="panel panel-default">
<div class="panel-body">{props.children}</div>
</div>
</div>
);
const TabListRow = props => (
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="card">
<h5 class="card-header">{props.cardtitle}</h5>
<div class="card-body">
<p class="card-text">{props.cardcontent}</p>
</div>
<div class="card-footer">{props.cardfooter}</div>
</div>
</div>
<div class="col-md-10">
<h2>{props.blockheader}</h2>
<p>{props.blockcontent}</p>
<p>
<a class="btn" href="#">
View details »
</a>
</p>
</div>
</div>
</div>
);
function App(props) {
console.log(<CDataRow myname="JoJo" email="jojo#ops.org" />);
return (
<div>
<TitleCard
titleheading="{Lex Integration Test}"
subtitle="Embedding Lex into a website"
/>
<LexChat
botName="TestReactBot"
IdentityPoolId="us-west-2:<redacted>"
placeholder="Placeholder text"
style={{ position: "absolute" }}
backgroundColor="#FFFFFF"
height="430px"
headerText="Store help"
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App version="1" />, rootElement);
After creating my identityPoolId In my own case, I had to attach these two policies AmazonPollyReadOnlyAccess and AmazonLexRunBotsOnly.
To do that Navigate to the IAM console and select Roles. In Roles find the Cognito roles you created and attach the policies.

Resources