Gatsby - change over-the-fold initial HTML - html

I'm building landing pages with the amazing Gatsby framework (version 2.16.1).
Everything would have worked perfectly, except that I can't find a way to make changes to the HTML that's being loaded before any script is loaded (the 'over-the-fold' initial HTML).
For example, if I change the HTML's background color in Gatsby - Users can wait up to 5 seconds since the 'over-the-fold' initial HTML is displayed, until the background color is applied.
I know about gatsby-browser.js and the ability to make global CSS files, but that's no use for me as I use a different color or background-picture for each landing page.
My question is: Can I affect the first loaded HTML (differently for each Gatsby page) in Gatsby or React?
Illustration: I color the background color as yellow, but the flow is like this -
HTML is first displayed (background=while) -->
3-5 seconds later -->
all scripts are loaded, and background changes to yellow

#ksav answered the question in a comment to the question! Thank you!
The answer is using a function called onRenderBody under the gatsby-ssr.js file, as explained in the article that was mentioned: https://www.gatsbyjs.org/docs/custom-html/
exports.onRenderBody = ({setBodyAttributes,pathname,}) => {
// Differentiate between the landing pages here
switch(pathname) {
case 'landing_page_a':
case 'landing_page_b':
}
// Affect the HTML that gets loaded before React here
setBodyAttributes({
style: {
backgroundColor: 'red',
},
});
}
The funny thing is, that I've already bumped into this article before, but didn't think it was relevant because it talked about server-side-rendering, and I know that Gatsby is server-less. After #ksav 's comment, I re-read it, and understood that the server-side-rendering happens during Gatsby's build process, and not during run-time (i.e. when the user enters the landing pages).

Can I affect the first loaded HTML (differently for each Gatsby page) in Gatsby or React?
Yes, you can directly in the JSX React code. Google has documentation how you can optimize CSS delivery so your above-the-fold content is always styled correctly. It comes down to using inline CSS for all your components above the fold. With inline CSS your HTML elements are always styled when they are loaded because the styling is part of the HTML code.
See the React documentation for how to handle inline styles in React.
An example from the Gatsby tutorial:
src/pages/index.js
import React from "react"
export default () => (
{/* inline CSS */}
<div style={{ margin: `3rem auto`, maxWidth: 600 }}>
<h1>Hi! I'm building a fake Gatsby site as part of a tutorial!</h1>
</div>
)

Related

Angular html custom element from typescript [duplicate]

I'm setting HTML returned from the API in my Angular component:
<div [innerHTML]="content"></div>
content in this example is something like this:
<table>
<tr>
<td>[audioPlayer:file.mp3]</td>
</tr>
</table>
Now I would like to inject the actual component inside the table cell.
If I make a certain container, I can create the component with createComponent:
audioPlayerComponentRef: ComponentRef<AudioPlayerComponent>;
#ViewChild('placeholder', { read: ViewContainerRef }) container;
const factory: ComponentFactory<AudioPlayerComponent> =
this.componentFactoryResolver.resolveComponentFactory(AudioPlayerComponent);
this.audioPlayerComponentRef = this.container.createComponent(factory);
Then I can inject it into a container in the template:
<div #placeholder></div>
However, going back to my original goal, I can't use such a container, as the component needs to be injected into a specific position into an innerHtml block.
I've been brainstorming all day, but I can't see any way to achieve this.
Generally speaking, this is contrary to the way Angular works. [innerHTML] is not parsed for any Angular functionality. No component selectors or even a ViewContainerRef can be found there. Rather, even remotely suspicious HTML, CSS and JS is removed as a security measure as Angular only trusts its own templates.
So InnerHTML is a no-go. But I was in the same boat myself and have written a library to solve this exact problem. With it, you can freely load dynamic components into strings without compromising security. If you're still stuck on this, you might wanna have a look at it.

Easiest way to add html to a React component

Say I have the following component in my web app:
class About extends React.Component {
render() {
return (
<div className="about">
/* place html here. */
</div>
)
}
}
I'm currently practicing my understanding of raw html/css. So ideally, I want to be able to write up this about section somewhere else. E.G., an about.html and an about.css, an about.html with some inline css, or a <style> tag. Or most ideally, lower down in the same file that defines this component.
The idea is I want to separate my practicing of hmtl/css from the React specific / JSX code.
Is this possible? and if so what is the least friction route assuming that this is not a very mission critical project and I'm fine with taking a less secure or more hacky approach?
If you want, you can declare a variable elsewhere or write a different component separate from this block and bring it in. But at the end of the day, you're still going to be writing JSX. You can still use .css to style your JSX the same as you would html, there's really no difference.

Highlighting "current" navigation link when using template navigation menu

I'm inexperienced at coding and trying to build a pretty simple site with some HTML and CSS in Dreamweaver. I'd like my navigation menu to highlight the current page a viewer is looking at, and I've found different ways to do this. However, to make life easier as the site evolves, I've made the navigation menu an uneditable region of a template. I'm therefore finding myself unable to make the coding changes (e.g., giving a unique class to each link or a unique body id to each page) to each page that would seemingly allow me to highlight the current page link. Thanks!
A simple way to do this is with Dreamweaver template attributes which allow you to have editable tag attributes:
https://helpx.adobe.com/dreamweaver/using/defining-editable-tag-attributes-templates.html
While editing your template, if you put your cursor on the nav item class, you could then go to Modify > Templates > Make Attribute Editable.
Then, when editing the page based on the template, you'll be able to add an active class.
You could use jQuery for this to detect a word in url:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
$(document).ready(function($) {
if(window.location.href.indexOf("contact") >= 0){
$(".contactLink").addClass("active");
}
});
</script>
<style>
.active { color: black; font-weight: bold }
</style>
contact
This could add a class to the menu item that has the word "contactLink" as a class. So long as you have this js on all pages (put it in a file rather than hard coded on all pages) it will work. If you copy the above code into a page called test.html the link is normal. change the name to contact.html and it goes black..
Give each menu item a class, and then duplicate the code above for however many items you have.
There are more dynamic ways of doing it, but if you don't have millions of pages, is a nice easy way.

Reveal div when link is clicked

Using mootools.js 1.3.2 and mootools-more.js
As far as I can tell this is supposed to reveal the div and also hide the content and linkTab divs at the same time.
$('blogLink').addEvent('click', function(){
$('homeLink').removeClass('active');
$('linkTab').removeClass('active');
$('blogLink').addClass('active');
content.slideOut();
linkTab.slideOut();
blogLink.slideIn();
});
This is the HTML
Blog
<div id="blogContent">
content here
</div>
It all works properly and that's OK but in addition to this, I also want to be able to give people a URL like http://mysite.com/#blogLink and have that blogContent div opened. When I do that now, it takes me to the top of the page and the blogContent div is hidden.
How do I do achieve that? I did try adding the mootools-smoothscroll.js and using the method outlined here http://davidwalsh.name/smooth-scroll-mootools but that just broke the entire page - would not load properly.
I have zero experience with mootools and weak on Javascript so please excuse me if I take a while to 'get' what you're trying to explain.
Many thanks.
First, are you particularly attached to MooTools? If you're a JavaScript newbie, jQuery is probably easier to use and definitely has a larger support community. But I'll post a solution that should work in MooTools for now:
If I understand you correctly, what you want to achieve is the following:
The anonymous function you posted will run when "Blog" is clicked
The function will also run if someone visits the page with #blogLink in the URL.
That's not too difficult to achieve:
// Once the DOM has loaded - so that our elements are definitely available
window.addEvent('domready', function() {
// Check for #blogLink hashtag, and reveal blog
if(window.location.hash == 'blogLink') { revealBlog(); }
// Make sure blog is revealed when link is clicked
$('blogLink').addEvent('click', revealBlog);
});
function revealBlog() {
$('homeLink').removeClass('active');
$('linkTab').removeClass('active');
$('blogLink').addClass('active');
content.slideOut();
linkTab.slideOut();
blogLink.slideIn();
}
You could also change your link mark-up to:
Blog
To make sure they're always on the correct link when the blog is revealed.

Override a CSS style on one page

I have a page (http://www.gardensandhomesdirect.co.uk/newhomepage)
I want to make the center column (#content-column) 930px for this page only, which will eventually become the homepage.
The CMS used is NetSuite, and is notoriously difficult to work with.
What is the best way to do this? Is it possible with just CSS/HTML commands or JavaScript?
Since it's a CMS you probably cannot add markup easily so I'm thinking some jQuery would be a simple solution here...
$(function () {
var path = location.pathname.substring(1);
if (path) {
var regex = new RegExp('newhomepage$', 'gi');
if (regex.test(path)) $('#content-column').addClass('yourClass');
}
});
This should add "yourClass" to the element just on that page.
Then you can add to your external CSS...
.yourClass {
width: 930px !important;
}
I feel your pain
I have used Netsuite extensively and found )after many hours of hair pulling and expletives) that the best solution (for us) has been to create the home page and any unique landing pages as Hard coded Hosted pages (hosted on Netsuite) and reserve Netsuite's CMS system for item pages where you need the add to cart functionality.
Take it from me in the long run it'll save you hours of frustration :-)
Of course you can use Netsuite tags all over the place as long as you host the pages in your "site" folder
I have no experience with Netsuite so please take this as is..
I would try to add a custom style tag to the document like this:
<style>
#content-column{
width:930px !important;
}
</style>
If you only have access to the HTML of that page, then put an inline style attribute in the center column's HTML. Example:
<div id="content-column" style="width: 930px;">