inject a react component as background-image - reactjs

I am looking for the best way to inject a dynamically built image as my background image. I can build the image and I can display it as a div but I want it as the background of my body.
<div className="App">
<mycomonent />
</div>
works but it is not what I want
<body styles="background-image: {mycomponent}"></body>

You can change using regular DOM object within React.
document.body.style.backgroundImage = `url("https://www.placecage.com/c/460/300")`;
Working Demo

Related

Issues using react-loading-overlay

I have a simple react app, and im trying to add a simple loading overlay.
I saw the most common usage is react-loading-overlay.
My main app.js structure looks like that, I have a simple menu and a deck.gl map
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
If I get it correctly, to use the loading overlay, I need to do something like that (using true for testing):
<LoadingOverlay
active={isActive}
spinner
text='Loading your content...'
>
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
</LoadingOverlay>
But once I do that, my entire app page, instead of filling the whole screen, just takes the top 20% of the screen (and the rest is empty white).
Why wrapping my component with the LoadOverlay component causes the whole page to look weird?
Do I need to "play" with the CSS for the LoadOverlay component?

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.

React - load external js which outputs HTML into React Slick component

Just wondering what the procedure is loading an external script into a component which renders HTML?
I call a script, which returns me an unordered list which i want to use for an image carousel it looks something like this but currently isn't working
this is what i have inside my render
return(
<Slick {...settings}>
<script
type="text/javascript"
src="https://some.external.script.js"
/>
<div
class="render-html-here-from-script"
/>
<script>
SomeScript.require(['xxx'], function(arg)
{arg.loadAll().done(function(embed) {
// code here gets list and binds above in div
})}
)
</script>
</Slick>
)
the above code works fine if I just copy/paste straight into a standard HTML page
Thanks

Angularjs, replace html content when angular is loaded

I have an angular app with a page and dynamic content.
I use ui router for routing.
I want user to see static html which server side rendering will return it, and when angular is loaded, change html content with ur router templates.
sample static html is:
<div ui-view>
<div>Lorem Ipsum</div>
<p>Lorem Ipsum</p>
<span>Lorem Ipsum</span>
<div>
sample ui router template is:
<div>
<div>{{myModel}}</div>
<p>{{myModel2}}</p>
<span>Lorem Ipsum</span>
<div>
My aims:
User should see some static html, before dynamic content is loaded. Dynamic content will replace it.
Search engines should track static files, not something like <p>{{myModel2}}</p>
I think you can make static content visible before ui-router is resolved like this:
<ui-view>
<div>Lorem Ipsum</div>
<p>Lorem Ipsum</p>
<span>Lorem Ipsum</span>
</ui-view>
Using ui-view as custom tag will render inner HTML without any changes to it, however when route is resolved this content will be replaced with actual route template.

AngularJS - looking to add and remove an iframe based on dom events

I would like to add an iframe to a page when certain links are clicked and remove it when other mouse events happen on the page. From what I can see, it seems that using an AngularJS directive would be the best way to do this. What I'm not sure about is what is the best way to format the directive. I'm thinking of making the directive at the attribute level...something like this:
<div myIframeDirective></div>
What I'm not sure of is the best way of removing/adding the directive contents (an iframe and a header above it) when various click events happen on the main page. Not looking for anyone to write the code for me...just looking for examples of how this can be best accomplished.
You should be using ng-if.
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
Here's a working example:
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
</div>
In Angular, ng-if will remove the iframe from the DOM if it is false.
This means the URL will NOT be requested until ng-if is true.
<iframe ng-if="frameDisplayed" ng-src="{{src}}"></iframe>
And use the link
Toggle
Then in your controller, you can control what your iframe display:
$scope.src = 'https://angularjs.org';

Resources