polyfill-service
Version:
A polyfill combinator
114 lines (73 loc) • 8.43 kB
HTML
{{>header}}
{{>nav}}
<div class="o-techdocs-main o-techdocs-content">
<h1>Examples</h1>
<p>Here are some common recipes and advice for constructing polyfill requests. This isn't a substitute for the full API reference, and is not intended to show all possible permutations.</p>
<h2 id='basic'>Basic case</h2>
<p>The simplest use: consider default polyfills, bundle, minify and and return those which are required by the current browser:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.min.js'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>This example is minified by including <code>.min</code> in the URL. All the other examples on this page are not minified, so you can see the metadata included at the top of the response, but any response can be minified by adding <code>.min</code> in the same way as shown above.</p>
<h2 id='aliases'>Using aliases</h2>
<p>Consider only the <code>Array.prototype.map</code> and <code>modernizr:es5array</code> polyfills, the first only if needed by the browser, the second regardless of the user-agent. No <code>.min</code> here so the result is not minified.</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Array.prototype.map,modernizr:es5array|always'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>If you don't specify any <code>features</code>, 'default' is assumed, but you can also specify default explicitly if you want to combine it with something else. This example uses the default set plus fetch:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=default,fetch'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>Use the <code>es6</code> alias to include all features that are part of ECMAScript 6 (for which we currently have polyfills):</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=es6'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<h2 id='override-ua'>Overriding the user-agent</h2>
<p>Consider default polyfills, but for an IE7 user-agent:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?ua=Mozilla%2F5.0%20(Windows%3B%20U%3B%20MSIE%207.0%3B%20Windows%20NT%206.0%3B%20en-US)'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<h2 id='flags'>Using flags</h2>
<p>It's often a good idea to use the <code>gated</code> flag to wrap polyfills in a feature-detect. Some people prefer not to do this and instead just trust the browser targeting, but to guard against mistargeting, incorrect user agent interpretation, and conflicts with other polyfills that may be on the same page, you can apply feature-detect gating to all features in the bundle at once:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Element.prototype.classList,Array.from,Document&flags=gated'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>Use the <code>always</code> flag to force a polyfill to be returned regardless of whether the user-agent requires it:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Element.prototype.classList|always,Array.from,Document|always&ua=chrome/37'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>This example uses a useragent override of chrome/37 to demonstrate one of the problems of using <code>always</code>: in Chrome, there is no polyfill for Document that makes sense, because even in those browsers that do need the polyfill, no two browsers use the same one. As a result, even if you specify <code>always</code> on this feature, you'll get no polyfill in chrome.</p>
<p>With both <code>gated</code> and <code>always</code>, you can apply them either at the feature-level using the pipe delimiter or to the whole request using the <code>flags</code> parameter. This example applies both flags to one feature but neither to the other:
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Element.prototype.classList|always|gated,Array.from'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<p>And this example applies both flags to the whole request:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Element.prototype.classList,Array.from&flags=always,gated'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<h2 id='rum'>Real user monitoring</h2>
<p>To help out the project with collecting compatibility data, please consider enabling the `rum` option:</p>
<div class='demo' data-src='{{host}}/v{{apiversion}}/polyfill.js?features=Element.prototype.classList,Array.from&rum=1&flags=always'>Your browser is too old to run the enhanced experience of {{host}}. Please upgrade to see this content.</div>
<h2 id='feature-detection'>Loading strategies</h2>
<p>There are many ways you can incorporate the polyfill service into your site's resource loading strategy, to suit different standards and rules.</p>
<h3>Async with callback</h3>
<p>We recommend the use of the <code>async</code> and <code>defer</code> attributes on <code><script></code> tags that load from the polyfill service, but loading from us in a non-blocking way means you can't know for certain whether your own code will execute before or after the polyfills are done loading.</p>
<p>To make sure the polyfills are present before you try to run your own code, you can attach an <code>onload</code> handler to the {{host}} script tag, use a more sophisticated <a href='https://davidwalsh.name/javascript-loader'>script loader</a> or simply use our <code>callback</code> argument to evaluate a global callback when the polyfills are loaded:
<pre><code><script src="{{host}}/v{{apiversion}}/polyfill.min.js?callback=polyfillsAreLoaded" defer async></script>
<script>
function polyfillsAreLoaded() {
console.log('Now to do the cool stuff...');
}
</script></code></pre>
<h3>Feature detection</h3>
<p>The polyfill service uses (and advocates) server side feature detection based on <code>User-Agent</code> identification, but you can also use the service with feature detection in the browser if you like. Just run the tests you want and construct a {{host}} URL, with an <code>always</code> flag to disable our user-agent feature-detection, and a <code>ua</code> identifier set to a supported browser:</p>
<pre><code>// Create a list of the features this browser needs.
// Beware of overly simplistic detects!
var features = [];
('Promise' in window) || features.push('Promise');
('IntersectionObserver' in window) || features.push('IntersectionObserver');
('after' in Element.prototype) || features.push('Element.prototype.after');
// If any features need to be polyfilled, construct
// a script tag to load the polyfills and append it
// to the document
if (features.length) {
var s = document.createElement('script');
// Include a `ua` argument set to a supported browser to skip UA identification
// (improves response time) and avoid being treated as unknown UA (which would
// otherwise result in no polyfills, even with `always`, if UA is unknown)
s.src = '{{host}}/v{{apiversion}}/polyfill.min.js?features='+features.join(',')+'&flags=gated,always&ua=chrome/50&callback=main';
s.async = true;
document.head.appendChild(s);
} else {
// If no polyfills are required, invoke the app
// without delay
main();
}
function main() {
console.log('Now to do the cool stuff...');
}</code></pre>
<p>You can view the above example <a href='https://jsbin.com/sufiboz/'>in a JSBin demo</a>. Doing live feature detection in the browser is one of our oldest feature requests, and we hope to support this out of the box at some point. Follow <a href='https://github.com/Financial-Times/polyfill-service/issues/84'>issue 84</a> for updates.</p>
</div>
{{>footer}}