Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onLoad prop removed from html.js - works in other files #30686

Closed
Primajin opened this issue Apr 5, 2021 · 7 comments
Closed

onLoad prop removed from html.js - works in other files #30686

Primajin opened this issue Apr 5, 2021 · 7 comments
Labels
stale? Issue that may be closed soon due to the original author not responding any more. status: needs more info Needs triaging and reproducible examples or more information to be resolved type: bug An issue or pull request relating to a bug in Gatsby

Comments

@Primajin
Copy link

Primajin commented Apr 5, 2021

Description

When I use the onLoad prop in my central html.js file it is being removed, while in other files it works as expected.

Steps to reproduce

Add a html.js file and add an element with onLoad attribute - for example a <link onLoad="stuff">

Primajin/gatsby-bug-onload@9658ec9

image
image

Expected result

The element is rendered with the onLoad attribute.

Actual result

The element is rendered without the onLoad attribute.

Environment

  System:
    OS: Windows 10 10.0.19042
    CPU: (8) x64 AMD FX-8370 Eight-Core Processor
  Binaries:
    Node: 14.15.3 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.11 - C:\Program Files\nodejs\npm.CMD
  Languages:
    Python: 3.9.3
  Browsers:
    Chrome: 89.0.4389.114
    Edge: Spartan (44.19041.906.0), Chromium (89.0.774.68), ChromiumDev (--> [posh-monokai] Black       DarkBlue    DarkGreen
DarkCyan    DarkRed     DarkMagenta DarkYellow  Gray
--> [posh-monokai] DarkGray    Blue        Green       Cyan        Red         Magenta     Yellow      White)
  npmPackages:
    gatsby: ^3.2.1 => 3.2.1
@Primajin Primajin added the type: bug An issue or pull request relating to a bug in Gatsby label Apr 5, 2021
@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Apr 5, 2021
@Primajin
Copy link
Author

Primajin commented Apr 5, 2021

For example when I use helm I can push a link element with an unload attribute to the header with no problem

@LekoArts LekoArts added status: needs more info Needs triaging and reproducible examples or more information to be resolved and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Apr 6, 2021
@LekoArts
Copy link
Contributor

LekoArts commented Apr 6, 2021

I think this is the same as: vercel/next.js#12984

Especially relevant:

onload is handled by React so I assume it's read as if it's a React event handler.

Also, as laid out in https://www.gatsbyjs.com/docs/custom-html/

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.

So I'd recommend using setHeadComponents to add your Stylesheets. A popular plugin is also doing this: https://github.com/codeAdrian/gatsby-omni-font-loader/blob/main/components/AsyncFonts.tsx

@Primajin
Copy link
Author

Primajin commented Apr 6, 2021

Ahh thanks @LekoArts I'll try out the plugin - that looks promising. I'm very new to Gatsby so I didn't knew about setHeadComponents with gatsby-ssr.js - maybe it's worth making this removal behaviour more clear in the docs though - or via a comment in the pristine html.js - as it happens silently and thus it's unexpected.

@github-actions
Copy link

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

@github-actions github-actions bot added the stale? Issue that may be closed soon due to the original author not responding any more. label Apr 27, 2021
@github-actions
Copy link

github-actions bot commented Jun 6, 2021

Hey again!

It’s been 60 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.
Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to comment on this issue or create a new one if you need anything else.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community! 💪💜

@github-actions github-actions bot closed this as completed Jun 6, 2021
@wybitnygracz
Copy link

wybitnygracz commented Apr 10, 2022

@LekoArts

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.

I tried this way, but then also "onload" is removed.

 let hc = getHeadComponents();

    hc.forEach(el => {
        if (el.type === "style") {
            el.type = "link";
            el.props["href"] = el.props["data-href"];
            el.props["rel"] = "preload";
            el.props["as"] = "style";
            el.props["onload"]="this.onload=null;this.rel='stylesheet';"
            el.props['ANY_OTHER_TAG'] = 'works as expected'; 
        }
    })

@waldemar-krumrick
Copy link

A few days ago I was facing this issue. So, what if you really need to define the onload style attribute on html.js? You can do it this way:

  1. Implement a temporal attribute name (a unique reserved name across your site) on gatsby-ssr.js.
    So, instead of adding an attribute labeled "onload" just use "_force_onload_html_attribute".
    You can do the same with the value for this attribute. Instead of the javascript itself, you can add the value as "_force_onload_html_attribute_value".

    CODE:

exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {     `
    getHeadComponents().forEach(el => 
    {
        if (el.type === 'style' && el.props['data-href']) 
        {
            el.type = 'link'
            el.props['href'] = el.props['data-href']
            el.props['rel'] = 'stylesheet'
            el.props['type'] = 'text/css'
            el.props['media'] = "print"
            el.props['_force_onload_html_attribute'] = "_force_onload_html_attribute_value"
            delete el.props['data-href']
            delete el.props['dangerouslySetInnerHTML']
        }
    })
}
  1. Now the trick, is to look for every .html generated as part of the build and replacing those 2 reserved words with the values you want to. The place where we can implement this is on the gatsby-node.js using the onPostBuild API.
//auxiliary function to find HTML files recursively.
const walk = (dir, filterExtension) => {
	try {
	  let results = [];
	  const list = fs.readdirSync(dir);
	  list.forEach(file => {
		file = path.join(dir, file);
		const stat = fs.statSync(file);
		if (stat && stat.isDirectory()) {
		  // Recurse into subdir
		  results = [...results, ...walk(file, filterExtension)];
		} else {
		  // Is an Html file.
		  if (file.endsWith(filterExtension)) {
			results.push(file);
		  }
		}
	  });
	  return results;
	} catch (error) {
	  console.error(`Error...`, error);
	}
  };
  
// this functions will replace the two temporal html attribute and value to the actual value.
  const edit = filePath => {
	const oldContent = fs.readFileSync(filePath, {encoding: 'utf8'});
	const regex = /_force_onload_html_attribute/;
	const replaceVal = 'onload';
	const newContent = oldContent.replace(regex, replaceVal);

	const regex2 = /_force_onload_html_attribute_value/;
	const replaceVal2 = "this.media='all'; this.onload = null"
	const newContent2 = newContent.replace(regex2, replaceVal2);
	fs.writeFileSync(filePath, newContent2, {encoding: 'utf-8'});
	console.log(`Edited file: ${filePath}`);
  };

// onPostBuild API
exports.onPostBuild = async ({_,reporter},  pluginOptions) => 
{
			const public_dir = `${__dirname}/public`	
			const filePaths = walk(public_dir, '.html');
			filePaths.forEach(filePath => edit(filePath));
}

Then, the final result in the HTML is something like:

<link data-identity="gatsby-global-css" href="/styles.830f820405b440b0141f.css" rel="stylesheet" type="text/css" media="print" onload="this.media='all'; this.onload = null"/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale? Issue that may be closed soon due to the original author not responding any more. status: needs more info Needs triaging and reproducible examples or more information to be resolved type: bug An issue or pull request relating to a bug in Gatsby
Projects
None yet
Development

No branches or pull requests

4 participants