February 18, 2019
Living Dangerously
Have you ever wanted to use a native <script /> inside your React components, and just wanted a quick, easy solution? Before you reach for a lifecycle function, an Effect, or an effigy, try living dangerously, with React's dangerouslySetInnerHTML.
const MyComponent = () => (
<script
dangerouslySetInnerHTML={{ __html: `
console.log('Wow, this is great.');
`}}
/>
);
Using this method, your script will load like an old, normal, native script tag.
But why might you want to do something like this, aside from the fact that it's expedient and declarative? Let's look at three common use-cases.
1. Third-Party
First and foremost, it's straightforward to load a third-party resource using this approach.
import * as snippet from '@segment/snippet';
const Layout = () => (
<script dangerouslySetInnerHTML={{ __html: renderSnippet() }} />
);
2. User Timings & Custom Metrics
In order to improve performance, you must start by measuring accurately! With the User Timing spec, it's now possible to measure not only Load and DOMContentLoaded, but any number of timings.
const MyMeasuredComponent = () => (
<Image src='cats.jpg' />
<script
dangerouslySetInnerHTML={{ __html: `
performance.clearMarks("img displayed");
performance.mark("img displayed");
`}}
/>
);
For further reading on what you can do with user timings and custom metrics, check out this great post from SpeedCurve.
3. Structured Data
To comply with Schema.org, it's necessary to render a script with type application/ld+json. Here's what a <JsonLD /> component might look like, with our approach.
import PropTypes from 'prop-types';
import React from 'react';
const JsonLD = ({ data }) => (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(data, null, 4),
}}
/>
);
JsonLD.propTypes = {
data: PropTypes.shape({}).isRequired,
};
export default JsonLD;
Now we can easily render the necessary scripts.
const Layout = () => (
<JsonLD
data={{
'@context': 'http://schema.org',
'@type': 'Organization',
name: 'Rent-a-Cat, Inc.',
url: 'https://www.example.com',
logo: 'https://www.example.com/rent-a-cat.jpg',
}}
/>
);
Conclusion
There you have it, a dead-simple method for loading scripts, with three common use-cases.
Need something with a bit more firepower? Try one of these fully-fledged libraries: