Gatsby Image inside Flickity carousel - reactjs

I am creating a gatsby website that uses the flickity-react-component to display a slider with product images. I believe that I should use the gatsby image to make it load faster, but when I try it, the Image does not display (it is 0x0 pixels).
This is the code I am trying to run:
const ThirdPage = ({ data }) => {
...
function Carousel() {
return (
<Flickity
className={'carousel'} // default ''
elementType={'div'} // default 'div'
options={flickityOptions} // takes flickity options {}
disableImagesLoaded={false} // default false
reloadOnUpdate // default false
static // default false
>
<Img fluid={data.imgPrincipal.childImageSharp.fluid} alt="Mulher a lavar o cabelo com o chuveiro ecológico" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/architecture" />
</Flickity>
);
}
The "Img" is the one using the gatsby image, the others are what I had before.
This is the result
I don't get an error when running this, I believe this might be because gatsby-image creates a div.
Can someone help me make this work? I am a beginner, so if it's something very advanced, I would appreciate an alternative ... Thank you.

Indeed, gatsby-image is not only a simple image. It creates a wrapper with a few nested div HTML structure inside to make the blur effect and the rest of the improvements.
Take a look at gatsby-image docs:
Note: gatsby-image is not a drop-in replacement for <img />. It’s
optimized for fixed width/height images and images that stretch the
full-width of a container. Some ways you can use <img /> won’t work
with gatsby-image.
It may not work with all sliders.
I've used it with other sliders that accept a nested structure inside, not only a single <img> tag such as Swiper or Slick.

Related

Can I preload an image for a component before it gets used in nextjs

I'm close to deploying a project with NextJS, however I noticed that a lot of the images take quite a bit of time to appear on screen.
I've installed sharp and set the priority to true, but even then images appear pretty slowly.
There's one part of the application, where a specific component gets conditionally rendered. That component has a small illustration included (about 30-50kb depending on the type) and it only shows for 2 seconds, since it's a short confirmation for the user.
There's also another page, which has a bigger illustration on it (about 500kb), which I would love to preload, since it takes a good second to load, when the component gets rendered.
Basically what I'd like to do, is fetch the needed images/illustrations ahead of time, before they need to be used, so that they appear instantaneously for the user.
Is there a way to do this in NextJS? Also happy to move away from the Next/Image component and just use img tags to do this.
Not sure whether code helps in this case, but here is how I display the 500kb image:
<div className="result__illustration">
<Image
src={resultIllu}
alt=""
layout="responsive"
objectFit="contain"
priority={true}
/>
</div>
This is possible using new Image() and then adding an src attribute to it. I made a simple example to illustrate a memoized version of this behavior:
codesandbox
const PreloadedImage = preloadImage("https://via.placeholder.com/700x500");
export default function App() {
return (
<div className="App">
<PreloadedImage alt="Placeholder image" />
</div>
);
}
function preloadImage(src) {
const image = new Image();
image.src = src;
return function PreloadedImage(props) {
return <img {...props} src={src} />;
};
}

Make images in a text clickable in React

I'm building a website where I get a blog post from an API call. The body of the post is just html code mixed with text, images and even objects like youtube videos (it is build with ckeditor in the back). Everything is working as expected but I would like to make images clickable. Clicking the image, would open a modal in lightbox style.
I was considering extracting all the images (if any) from the body and making a gallery at the bottom of the post. But I think that would be more elegant just making images clickable and opening the dialag without showing them twice along the post.
An example of the response:
body: "<p>this is a text with some images: <img src='path/to/image1' /> and <img src='path/to/image2' /> how to make them clickable in React?</p>"
That body is rendered this way:
<GridItem xs={12} sm={8} md={8}>
<div dangerouslySetInnerHTML={{ __html: text }} />
</GridItem>
You can use the onClick event in your image:
<img src='path/to/image2' onClick={() => {aFunction}} />
ps: if you want to, you can add a className to put a cursor:pointer too.
I think this might help you
first of all, you need to cover the content of blog post (returned HTML from API call) into one single wrapper div.
after that, you can need to get all the elements of blog post using javascript like the example below
const elements = document.getElementById("wrapper").elements
now you can iterate throw all elements in blog post including the images
elements.forEach(item => {
if (item.type == "img")
// do this
})
I will edit the second code example in a few minutes

How to prevent Gatsby image from blurring a logo with every reload?

I've read through the gatsby-image docs but can't figure out how to turn something off. By default, it seems gatsby-image loads a thumbnail of an image, then loads the image progressively. Basically a nice placeholder effect. But I find that my logo keeps blurring everytime I change pages. Here's my code:
<StaticQuery
query={graphql`
query {
file(relativePath: { eq: "appendto_logo.png" }) {
childImageSharp {
# Specify the image processing specifications right in the query.
# Makes it trivial to update as your page's design changes.
fixed(width: 150) {
...GatsbyImageSharpFixed
}
}
}
}
`}
render={data => <Img fixed={data.file.childImageSharp.fixed} />}
/>
Any thoughts? How to prevent that blurring effect? Or the thumbnail loading effect...
Switching to GatsbyImageSharpFixed_noBase64 solved it (instead of just ...GatsbyImageSharpFixed)
Update
critical is now deprecated in favor of loading:
- <Img critical fixed={ ... } />
+ <Img loading="eager" fixed={ ... } />
Also use _noBase64 sharp fragments to completely remove the blur effect, as #epsilon42's comment & Kyle's answer suggested.
And finally, to persist a component (navigation bar, etc.) between page load, you can wrap the pages in a layout with that component.
Original answer
I think you can pass in a critical prop to Gatsby Image, like this: <Img critical fixed={ ... }> It will always load the image immediately. You might want to add fadeIn in there as well:
Images marked as critical will start loading immediately as the DOM is parsed, but unless fadeIn is set to false, the transition from placeholder to final image will not occur until after the component is mounted.
Gatsby Image docs
To avoid the blurring effect you could just hide the placeholder using the placeholderStyle attribute:
<Img fixed={data.logoImage.childImageSharp.fixed} placeholderStyle={{ visibility: "hidden" }}/>

`rexxars/react-markdown` plugin usage or alternative for rendering React markdown

I'm trying to render some html, stored in a DB, and put a component inside.
It'd look like this:
import ReactMarkdown from 'react-markdown/with-html';
const inlineCode = (props) => <Gist id={props.value} />;
const source = '`7df0c9a5d794504a28bd3256b7bf5c4f` <p>asdasdasd</p><h1>title</h1>';
ReactMarkdown is used like this:
<ReactMarkdown source={source} renderers={{ inlineCode }} escapeHtml={false} />
The result is is rendered properly and the block is also, but isn't, the contents are outside of the block.
If I wrap the whole source with a <div>, the <Gist/> is rendered as text and <p>/<h1> are rendered properly.
What am I missing? I'm trying to store html with custom components inside, <Gist/> is just an example. Suggestions for a (more) suitable library are also welcome. Example ideal source I'd like to store in a db and then render in a React component:
<div>
<p>
<CustomReactComponent/>
<br/>
test
</p>
<Gist/>
</div>
Okay I found this lib: https://github.com/probablyup/markdown-to-jsx
If your source looks like:
const source = `<gist id="yourIdHere" /> <h1>asdasdasd</h1>`;
<Markdown
options={{
overrides: {
gist: {
component: renderGist,
},
},
}}
>
{content}
</Markdown>
It renders both the <Gist> and the normal <h1> as <h1. Paragraph tags seem to be automatically added if you add line breaks and something like # Title is also automatically wrapped.
<Gist> in source is converted to lowercase, so it'd only matter for the overrides object (lowercase again). Handles all my custom stuff and html predictably.

Displaying gifv with react

I've been trying to view the imgur format gifv for a while but i just cant seem to get it working.
Been testing with img tags, video tags, iframes. So far only the iframe seems to work - but i cant resize the iframe due to browser limitations.
<img src="http://i.imgur.com/rCkPdZm.gifv" /> - nope
<video src="http://i.imgur.com/rCkPdZm.gifv"/> - nope
Any tips on how to display for example http://i.imgur.com/rCkPdZm.gifv
Thanks!
A gifv is not an image format, it's a made-up "extension" to make the landing page look like you have opened an image link directly, while being able to stream video instead of a much larger gif file. Use the "view source" option and go find out! :)
You can right-click on the gifv "image" and the browser should give you an option to "copy video url", which you can then use in a <video> element:
<video src="http://i.imgur.com/rCkPdZm.mp4" />
https://jsfiddle.net/xc4cqoh5/
In this context it doesn't matter if it's React or just plain HTML website, the solution is the same: you need to grab the URL of the actual video being played, not the gifv page that embeds it. It seems you can just replace the .gifv extension with .mp4. To make this answer relevant to the reactjs tag here's an example:
const Player = props => {
let videourl = props.videourl.replace('.gifv', '.mp4');
return <video src={ videourl } />;
};
ReactDOM.render( <Player videourl="http://i.imgur.com/rCkPdZm.gifv" />,
document.getElementById('container'));
http://jsfiddle.net/69z2wepo/47077/

Resources