Botkit embed with React + React-Router results in 404 error - reactjs

With React 16 and React-Router 4, I'm trying to using Botkit's embed code in a component, but it's just stuck in "Disconnected...reconnecting":
Code Sandbox is here
(I've removed the OnClick header and embedded_messenger divs as I want it to launch full-sized)
<div>
<iframe
title="botkit"
id="botkit_client"
src="//arrow-tarn.glitch.me/chat.html"
style={{ height: "80vh", width: "100%" }}
/>
<script src="//arrow-tarn.glitch.me/embed.js" />
<link rel="stylesheet" href="//arrow-tarn.glitch.me/css/embed.css" />
<script>var options = {}; Botkit.boot(options);</script>
</div>
);
When I run the app, I also get the following console error in Chrome:
GET http://arrow-tarn.glitch.me/%7B%7B%7Burl%7D%7D%7D 404 (Not Found)
Which of course translates unescaped to {{url}} not found.
I'm thinking it has to do with the initialization/options in React:
<script>var options = {}; Botkit.boot(options);</script>
Any clue what am I doing wrong?

The {{url}} problem is your browser parsing the template and rendering the (hidden) image tag. This isn't the issue causing it to fail.
Something about your iframe is causing the chat client to fail when connecting to the server... did you make any changes to the off the shelf code?

Related

Embed GitHub Gist using Remix

Is it possible to embed a Gist in Remix? I'm trying to embed the following gist in Remix using:
<script src='https://gist.github.com/AnthonyLzq/7d1cfeda389b7f5f38b62bd2640a32ba.js'></script>
But it is not displaying anything.
The problem is that React is trying to hydrate the <script> element. Since you don't want React to process this, you need to treat it as raw HTML.
<div
dangerouslySetInnerHTML={{
__html: `<script src="https://gist.github.com/AnthonyLzq/7d1cfeda389b7f5f38b62bd2640a32ba.js"></script>`,
}}
/>

How can I inject arbitrary string HTML content into the head of my gatsbyjs site?

I have a GatsbyJS site that I am working on where the main content source is a Wordpress install. One of the things I like to add to my sites is the ability to have placeholder areas in the site where I can control the content via the CMS. Usually I have a header_scripts area that goes at the bottom of the <head> tag, a body_scripts area that goes at the start of the <body> tag, and a footer_scripts area that goes at the bottom of the page <body>. With these three, I can usually integrate third-party add-ins pretty easily without having to do code deployments.
Sometimes I need to embed stylesheets, sometimes I need to embed script tags, and sometimes I need to throw in <meta> tags. Really the content could be anything. This data comes back as a raw string from my Wordpress GraphQL endpoint.
So now my question is, how do I get this content injected into my Gatsby site in the following places:
<html>
<head>
...
{header_scripts}
</head>
<body>
{body_scripts}
...
{footer_scripts}
</body>
</html>
I've found so far that I can just include the body_scripts and footer_scripts in a fairly regular manner in my Gatsby page template. In gatsby-node.js, I pass in the property values using the pageContext. It's kind of a bummer that they need to be wrapped in a <div /> tag, but they seem to work just fine.
import React from 'react'
export default class PageTemplate extends React.Component {
render = () => {
return (
<React.Fragment>
{this.props.pageContext.bodyScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.bodyScripts}} />
)}
{/* my page content here */}
{this.props.pageContext.footerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
)}
</React.Fragment>
)
}
}
Now for the real question. I am stumped on how to get the dynamic content from the header_scripts into the Gatsby server-side-rendering <head> tag. The closest thing I have found to being able to inject content into the head is to leverage the gatsby-ssr.js onRenderBody function. However, this seems to require pre-determined React component instances in order to function. I can't just pass it in plain raw string content and see the output in the page source:
export const onRenderBody = async ({
pathname,
setHeadComponents,
setHtmlAttributes,
setBodyAttributes,
setPreBodyComponents,
setPostBodyComponents,
setBodyProps
}, pluginOptions) => {
setHeadComponents(['<script>alert("hello");</script>'])
}
This results in an escaped string getting inserted into the <head> tag:
<html>
<head>
...
<script>alert("hello");</script>
</head>
<body>
...
</body>
</html>
I'm at a loss as to how to proceed. I can't just wrap my string in a <div /> tag like in the body because div tags can't go inside the head tag. I can't think of any head-capable HTML tags that would accept this kind of content.
The only idea I've had is to actually parse the string content into full React components. This seems daunting given the number of possible tags & formatting that I would need to support.
Am I going about this the wrong way? How can I get my arbitrary content into my Gatsby site's head tag?
It's a broad question and it will need some trials and errors to ensure that it's fully working without caveats in all scenarios but, among the things you've tried, you can add a few more options to the list to check which ones fit better.
Regarding the body_scripts and footer_scripts both can be inserted using the:
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
In any desired page or template. For the header_scripts and the meta tags (SEO), you can use the <Helmet> component. Basically, using this component, everything that is wrapped inside, it's becomes transpiled inside the <head> tag once compiled.
export default class PageTemplate extends React.Component {
render = () => {
return (
<React.Fragment>
<Helmet>
{this.props.pageContext.headerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.headScripts}} />
)}
</Helmet>
{this.props.pageContext.bodyScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.bodyScripts}} />
)}
{/* my page content here */}
{this.props.pageContext.footerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
)}
</React.Fragment>
)
}
}
However, if the data comes from a CMS, it won't be available in the SSR yet, so, one easy thing you can do is to customize the outputted HTML (html.js) that Gatsby generates in each compilation. From the docs:
Customizing html.js is a workaround solution for when the use of the
appropriate APIs is not available in gatsby-ssr.js. Consider using
onRenderBody or onPreRenderHTML instead of the method above. As a
further consideration, customizing html.js is not supported within a
Gatsby Theme. Use the API methods mentioned instead.
Run:
cp .cache/default-html.js src/html.js
Or manually, copy the .cache/default-html.js file and paste it /src folder. There you can customize the final HTML.

Using the HTML5 audio tag in Reactjs

I'm trying to use the HTML5 <audio> tag in React but it isn't being rendered.
This is my first time using React, so I might be missing something obvious.
I'm taking an existing Drupal frontend and re-building it in React.
All my other HTML is working, but the HTML5 <audio> tag is not.
Here's my simplest component to show the problem:
const NoData = () => (
<audio controls="" controlsList="nodownload">
<source src="/sites/default/files/fruits/apples.mp3" type="audio/mpeg" />
</audio>
);
When I view the page, the HTML is there, but it doesn't get rendered.
This HTML was copied from another part of my site verbatim, so it should work.
The React app is embedded in a Drupal page, so I copied the <audio> tag into the Drupal page itself, and it works there. It just doesn't show up inside React itself.
The file in the <source> tag is being read; if I change the file to one that is invalid, I get a warning in the Chrome dev tools.
So how do I use the HTML5 <audio> tag in React?
Just leave controls like this:
const App = () => (
<div>
<audio src="https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3" controls />
<audio controlsList="nodownload" controls>
<source src="https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3" type="audio/mpeg" />
</audio>
</div>
)
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Rendering code with syntax highlighting from a CMS

I am using a headless CMS(Strapi) and React on the frontend. I would like to render code blocks with highlighting using PrismJS (or anything).
In my render():
<div>
<pre>
<code className="language-css">{`p { color: red }`}</code>
</pre>
<h2>{this.state.title}</h2>
<div dangerouslySetInnerHTML={{ __html: `${content}` }} />
</div>
The code wrapped with <pre> tags serves as an example of what I'm trying to do.
The problem is that since I'm using the Strapi CMS, the code block not recognized by PrismJS. Here's how it's rendered:
The top part is the code directly written in my component while the bottom is returned from the CMS. In the WYSIWYG of the CMS I have the following <pre><code class="language-css">p { color: red }</code></pre>
Is there a way that I can write content with text and code and have the code highlighted properly?
This seems like a similar issue: React : Rendering a syntax highlighted code block
This solved my problem: https://github.com/akiran/react-highlight
Be sure to set your CSS in index.html and I added the following in my project:
<Highlight language="javascript" innerHTML={true}>
{content}
</Highlight>
Works perfectly! Hope this helps someone.

TypeError: images.forEach is not a function while using react-slick in Firefox 47.0

I am using react-slick for implementing carousel in React.
The carousel works fine in Chrome.
However, in Firefox (47.0) it gives an error: "TypeError: images.forEach is not a function".
I tried to have only image tags inside the react slick slider like the below code:
<Slider {...settings} className={classes.slider}>
<div className={classes.sliderdiv}>
<img src="..."/>
</div>
<div className={classes.sliderdiv}>
<img src="..."/>
</div>
<div className={classes.sliderdiv}>
<img src="..."/>
</div></Slider>
However, still I am getting the same error in Firefox.
The problem was present in react-slick version 0.21.0.
Updated the version to new one(0.22.3) and the issue is resolved.
Also, refer to this issue.

Resources