1 | # `@shopify/react-import-remote`
|
2 |
|
3 | [![Build Status](https://github.com/Shopify/quilt/workflows/Node-CI/badge.svg?branch=main)](https://github.com/Shopify/quilt/actions?query=workflow%3ANode-CI)
|
4 | [![Build Status](https://github.com/Shopify/quilt/workflows/Ruby-CI/badge.svg?branch=main)](https://github.com/Shopify/quilt/actions?query=workflow%3ARuby-CI)
|
5 | [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md) [![npm version](https://badge.fury.io/js/%40shopify%2Freact-import-remote.svg)](https://badge.fury.io/js/%40shopify%2Freact-import-remote.svg) [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@shopify/react-import-remote.svg)](https://img.shields.io/bundlephobia/minzip/@shopify/react-import-remote.svg)
|
6 |
|
7 | Asynchronous script loading for React.
|
8 |
|
9 | ## Installation
|
10 |
|
11 | ```bash
|
12 | $ yarn add @shopify/react-import-remote
|
13 | ```
|
14 |
|
15 | ## Usage
|
16 |
|
17 | The package provides a hook and component that are intended for loading external scripts. These utilities cache results by source, so only a single `script` tag is ever added for a particular source.
|
18 |
|
19 | ### useImportRemote()
|
20 |
|
21 | ```tsx
|
22 | import React from 'react';
|
23 | import {useImportRemote, Status} from '@shopify/react-import-remote';
|
24 | import {DeferTiming} from '@shopify/async';
|
25 |
|
26 | function MyComponent() {
|
27 | const {result} = useImportRemote(
|
28 | 'https://some-external-service.com/global.js',
|
29 | );
|
30 |
|
31 | if (result.status === Status.Failed) {
|
32 | // do something with error result
|
33 | }
|
34 |
|
35 | if (result.status === Status.Complete) {
|
36 | // do something with successful result
|
37 | }
|
38 |
|
39 | return null;
|
40 | }
|
41 | ```
|
42 |
|
43 | ### <ImportRemote />
|
44 |
|
45 | ```tsx
|
46 | import React from 'react';
|
47 | import ImportRemote from '@shopify/react-import-remote';
|
48 | import {DeferTiming} from '@shopify/async';
|
49 |
|
50 | interface RemoteGlobal {}
|
51 | interface WindowWithGlobal extends Window {
|
52 | remoteGlobal: RemoteGlobal;
|
53 | }
|
54 |
|
55 | function MyComponent() {
|
56 | return (
|
57 | <ImportRemote
|
58 | preconnect
|
59 | source="https://some-external-service.com/global.js"
|
60 | getImport={}
|
61 | onImported={(result: RemoteGlobal | Error) => {
|
62 | if (result instanceof Error) {
|
63 | // do something with error result
|
64 | }
|
65 |
|
66 | // do something with successful result
|
67 | }}
|
68 | defer={DeferTiming.Mount}
|
69 | />
|
70 | );
|
71 | }
|
72 | ```
|
73 |
|
74 | **source**
|
75 |
|
76 | Source of the script to load the global from
|
77 |
|
78 | **preconnect**
|
79 |
|
80 | Generates a preconnect link tag for the source’s domain using `<Preconnect />` component from [`@shopify/react-html`](../react-html)
|
81 |
|
82 | **getImport**
|
83 |
|
84 | Callback that takes in `window` with the added global and returns the global added to the `window` by the new script
|
85 |
|
86 | **onImported**
|
87 |
|
88 | Callback that gets called with the imported global or an `error` if one occurs
|
89 |
|
90 | **defer**
|
91 |
|
92 | A member of the `DeferTiming` enum (from `@shopify/async`) allowing the import request to wait until:
|
93 |
|
94 | - Component mount (`DeferTiming.Mount`; this is the default)
|
95 | - Browser idle (`DeferTiming.Idle`; if `window.requestIdleCallback` is not available, it will load on mount), or
|
96 | - Component is in the viewport (`DeferTiming.InViewport`; if `IntersectionObserver` is not available, it will load on mount)
|
97 |
|
98 | Note, changing any of these values while rendering will cancel the import.
|