React View source in Browser Newbe React - reactjs

I have a simple React site up and when I go to "View Source" in Chrome, It doesnt show much of the markup.Mostly JS imports. But if I click on an element with Dev tools up, it shows me the html as I would normally see it.
Can someone explain this to me?
Thanks

View source will have the the content what you have in build/index.html or public/index.html
index.html will have some <script> tags. Browser executes these JavaScript files in script tag and renders the page. We can say this as dynamic code or runtime generated html, css and other code.
So View Source will show only static contents, that is what you have in index.html. Its same as if you open index.html in any editor like notepad.
Where as when using dev tools you will see all runtime generated code. That is what dev tools indend to do.
And if you need to see the React components, state, props and other details, you need to use React dev tools for chrome
A simple example would be:
index.html
<html>
<body>
<div id="app"></div>
<script>
document.getElementById("app").innerHTML = "Hello World";
</script>
</body>
</html>
You will see the above code in View Source.
You will see below code in dev tools
<html>
<body>
<div id="app">Hello World</div>
<script>
document.getElementById("app").innerHTML = "Hello World";
</script>
</body>
</html>
Hope this is clear.

The actual source is mostly JS, between libraries that react uses, libraries you've imported, and the JS you've written.
When you write a view, typically in .jsx format, it is JS that is translated into HTML. So after the dom has populated by using the combination of the libraries and what you have written it is then available to view the html in the DOM, but the source will still only display the JS.
Sudo example
example.jsx
...
render() {
const example = ['a', 'b', 'c'];
return ( <div> { example.map((val) => (<p>{val}</p>)) } </div> }
}
...
Source
...
require('example.js')
...
DOM
...
<div>
<p>a</p>
<p>b</p>
<p>c</p>
</div>
...

Related

Connecting HTML iFrame to database

I have a database connected to dynamic pages. One of the columns in the database is an HTML embed code that I would like embedded on each page.
Is there a way of hardcoding the content of the database to an HTML Embed Frame via Velo? If so, how can this be done exactly?
There is no built-in way (click and play) but you can pass the html using postMessage from the website to the iframe.
For example:
Website code:
$w('#html1').postMessage(htmlFromTheDatabase)
HTML component code
<html>
<body>
<div id="content"></div>
<script>
window.addEventListener('message', message => {
console.log('message', message.data);
document.querySelector('#content').innerHTML = message.data
});
</script>
</body>
</html>
https://moshef9.wixsite.com/html-from-db

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.

Can't embed Facebook post into Next JS generated page

I am trying to embed a public FB post into the main page of my application. I am following FB guide and it's pretty simple. It works when I do it in .html file, but doesn't with Next JS.
Basically, instructions are that you need to insert this right after the body opening tag
<div id="fb-root"></div>
<script async defer crossorigin="anonymous"
src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&autoLogAppEvents=1&version=v9.0&appId={appId}" nonce={someNonce}"></script>
and then you put the other part wherever you want.
I even created a custom _document.js file and included this script, I can also see it in the browser. But the post does not get loaded.
Anyone had this kind of issue?
Assuming you already have the JS SDK loaded in your document, like you mentioned (you might also load the script on-demand via JavaScript if preferred).
// pages/_document
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<!-- additional code -->
<body>
<!-- additional code -->
<script
async
defer
src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.2"
/>
</body>
</Html>
);
}
}
You can then render a Facebook post inside one of your components with:
<div
className="fb-post"
data-href="https://www.facebook.com/20531316728/posts/10154009990506729/"
/>
For further details refer to the official Embedded Posts documentation.

Angular Dropdown (could be just IE): strange positioning of dropdown in IE

I'm taking baby steps with Angular and writing simple stuff and testing across browsers, I have a simple script to bind a menu against a JSON string array. I want to do the whole Angular MVC instead of Javascript DOM manipulation.
In my tests I can see a strange behaviour as to the positioning of the top of the menu in IE dependent upon which item is selected. Anyone know how to fix this? I would like to use an Angular friendly solution, like Bootstrap?
Menu looks good in Firefox and Chrome.
<html ng-app="myNoteApp">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-controller="myCarSelector">
<h2>Menu</h2>
<p>Make of car : <span ng-bind="selectedCarMake"></span></p>
<select ng-model="selectedCarMake" ng-options="val for val in carmakes"></select>
</div>
<script>
// was in separate file but pasted in for demo purposes
var app = angular.module("myNoteApp", []);
</script>
<script>
// was in separate file but pasted in for demo purposes
app.controller("myCarSelector", function ($scope) {
$scope.selectedCarMake = "BMW"; // default value
$scope.carmakes = ["Audi", "BMW", "Volkswagen"];
});
</script>
</body>
</html>
I like to accept answers and then move on to next question.
Here is a screen grab of the problem in IE 11
It seems browser default behaviour.

Jquery steps plugins conflict with CKeditor RTE plugins

Hi guys I am using this http://www.jquery-steps.com/Examples as my wizard form plugins.
I notice that it has a conflict with Ckeditor plugin with an error of Uncaught TypeError: Cannot read property 'unselectable' of null.
I just tried the solution on this post Ckeditor with jQuery form wizard but it doesn't fix the issue.
What is the best solution for this?
I guess you put the CKeditor right into the wizard HTML code. In that case what´s really important to understand is that jQuery Steps manipulates DOM objects. That´s really bad for javascript code in general.
To run javascript controls within jQuery Steps you have to ensure that:
no javascript code goes inside your wizard HTML
first jQuery Steps code executes and then the javascript code that belongs to the HTML inside the wizard HTML
Good example:
<script>
$(function ()
{
// first jQuery Steps
$("#wizard").steps();
// then components inside jQuery Steps
$("#editor").ckeditor();
});
</script>
<div id="wizard">
<h1>Title</h1>
<div>
<div id="editor"></div>
</div>
</div>
Bad example:
<script>
$(function ()
{
$("#wizard").steps();
});
</script>
<div id="wizard">
<h1>Title</h1>
<div>
<script>
$(function ()
{
$("#editor").ckeditor();
});
</script>
<div id="editor"></div>
</div>
</div>
Cheers,
Rafael

Resources