HomeReadmeBlogGive Me Feedback ↣

Living Dangerously

 
Man sitting precariously over cliff

Photo by Ashley Jurius

Have you ever wanted to utilize native <script /> within your React components, and just wanted a quick and easy solution? Before you reach for a lifecycle function, an Effect, or an effigy, try living dangerously, with React's <dangerouslySetInnerHTML />!

1
2
3
4
5
6
7
const MyComponent = () => (
  <script
    dangerouslySetInnerHTML={{ __html: `
      console.log('Wow, this is great.');
    `}}
  />
);

Using this method, your script will load like and 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 straight-forward to load a third-party resource using this approach.

1
2
3
4
5
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 new User Timing spec, it's now possible to not only measure Load and DOMContentLoaded, but any number of timings.

1
2
3
4
5
6
7
8
9
const MyMeasuredComponent = () => (
  <Image src='cats.jpg' />
  <script
    dangerouslySetInnerHTML={{ __html: `
      performance.clearMarks("img displayed");
      performance.mark("img displayed");
    `}}
  />
);

For further reading on the things you can do with user timings and custom metrics, check out this awesome blog post from SpeedCurve

3. Structured Data

In order 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.

1
2
3
4
5
6
7
8
9
10
11
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, along with three common use-cases.

Need something with a bit more fire-power? Try one of these fully fledged libraries:

Here are some other places you can find me:

© 2020, Jared Clifton-Lee