Inspiration:
- 3rdParty.io
- MiQ Creative Guidelines and Specifications
- YouTube Player Embed
- Disqus Embed
- Google Tag Manager Data Layer
- Facebook client side API
- Check-list Checklist Opquast - assurance qualité web
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, MAY are to be interpreted as described in RFC 2119. For readability, these words do not appear in all uppercase letters.
- must be GDPR compilant
- should not use device fingerprint
- must respect the Do Not Track user preference
- must not use user information in any URL querystring. Use the
post
's method payload instead.
TODO: TBD
- must use client design system
- must allow + char in email address1
- must play media only on user interaction2
- should not use deprecated HTTP-Based Public Key Pinning
- must use HTTPS for all resources, with at least a rate B by Qualys SSL Labs for all domains and subdomains used (CN and SAN). Must not use distrusted certificates3
- must support
gzip
andbr
encoding for text resources (JavaScript, HTML, CSS, JSON)4 - must support HTTP/2.0 and should support HTTP/3.0, if more than one resource is used
- must serve all resources with the
Timing-Allow-Origin: *
header5 - must serve all JavaScript resources that don't contains personal data with the
Access-Control-Allow-Origin: *
header, and loaded it withcrossorigin="anonymous"
attribute (or dynamicaly with the propertyscript.crossOrigin="anonymous"
)6 - must use correct (and official) media type (
Content-Type
header) - should support fixed versions for scripts and stylesheets to allow subresource integrity7
- must minify resources with tools likes Terser, SWC, esbuild, lightningcss, csso, cssnano, mozjpeg, etc.8
- must use appropriate formats for the web: AVIF, WebP, JPEG, MP4, etc.
For reasons of performance, console pollution/spam, global namespace pollution, name collision, clarity, bad practice, the API or widget:
-
may support to used via an iframe (isolated document context)9
-
must not use blocking scripts (no
document.write()
), all scripts must support async or defer loading -
must not use synchronous XMLHttpRequest
-
must not use any other Console API than
console.warn()
andconsole.error()
, unless a debug mode is enabled -
TODO: TBD reflow,
setInterval
, post message must not take more than 100ms to execute -
must use non-passive event listeners only when it's a necessity10
-
must send tacking data with fetch keep alive or beacon API (no pixel or "empty" tracking images)11
-
must not add method or properties to hosts and native objects, if not in an isolated document context
-
must use pure polyfills, if not in an isolated document context
-
may expose a global object, must not expose anything else, if not in an isolated document context:
may:
window.vendorName = { prop1: 123, prop2: 456, get prop3(){}, set prop3(){}, method1(){}, method2(){}, };
must not:
const value1 = 123; function method1(){}; window.method2 = () => {};
-
must provide a reliable way to programmatically know when the client side API (for read or write) is available:
(window.vendorName = window.vendorName || []).push( (vendorAPI) => {/*read/write vendor's API*/}, (vendorAPI) => {/*read/write vendor's API*/}, );
In case of iframe (isolated document context), the content of the frame should response to a post message to request the state:
window.postMessage("vendornameapiready", targetOrigin, transfer)
12. In case of pure CSS code, define a global variable. -
must provide a reliable way, when write data is needed, use at least one of the following methods (in preference order):
-
script querystring:
<script src="https://3rdpty.com/script?tenant=1234&version=5678" defer></script>
or<script src="https://3rdpty.com/1234/5678/script" defer></script>
-
attributes of the script:
<script src="https://3rdpty.com/script" defer data-tenant="1234" data-version="5678"></script>
-
to register statements:
(window.vendorName = window.vendorName || []).push( ["method1", arg1, arg2], ["method2", arg3, arg4], );
-
-
must provide a reliable way to programmatically interact with vendor's events13:
window.addEventListener("vendornamesomething", ({detail}) => {/*do something with the detail*/}); // Or (window.vendorName = window.vendorName || []).push( (vendorAPI) => vendorAPI.addEventListener("something", (event) => {/*do something with the event*/}), );
The name of events must respect the naming convention of the HTML standard (lowercase, concatenated, alpha only, present form, etc.)14.
-
must name global tokens (events name, global JS variables, DOM elements ID, cookie name / storage keys, CSS variables, etc.) with at least 4 chars length and prefixed with the vendor name (that start with an alpha char)15
-
must not use CSS
!important
specificity -
must not use
unload
event. Usepagehide
instead16 -
must not keep references to
window.opener
when it's not necessary17 -
must not keep open connections (IndexedDB, WebSocket and WebRTC) when the page is hidden18
Footnotes
-
Picto thématique Règle n° 23 - Le site accepte les alias mail contenant le signe + - Checklist Opquast ↩
-
Règle n° 119 - Les vidéos sont déclenchées par l'utilisateur - Checklist Opquast and Règle n° 120 - Les sons sont déclenchés par l'utilisateur - Checklist Opquast ↩
-
Règle n° 192 - Toutes les pages utilisent le protocole HTTPS - Checklist Opquast, Règle n° 193 - Les certificats de sécurité sont signés et en cours de validité - Checklist Opquast and Google Online Security Blog: Distrust of the Symantec PKI: Immediate action needed by site operators ↩
-
Règle n° 219 - Le serveur transmet des contenus compressés aux clients qui les acceptent - Checklist Opquast ↩
-
Muted errors - HTML Standard (errors for cross-origin scripts are muted) ↩
-
Subresource Integrity and Major sites running unauthenticated JavaScript on their payment pages – Terence Eden's Blog ↩
-
Règle n° 223 - Les scripts du site sont minifiés - Checklist Opquast, Règle n° 222 - Les feuilles de style du site sont minifiées - Checklist Opquast, Minify and compress network payloads and Minify CSS. ↩
-
The purpose is to make a separation layer between first party and third party and it dependencies for risk mitigation of:
- availability issue
- invalid/incorrect HTML syntax
- cookies name conflict
- javascript global variables conflicts
- incompatible host object extension
- javascript library version conflict
- style conflict/override
- script errors
- security issue (data leaking, malware, etc.)
- web performance (blocking rendering, blocking main Javascript thread)
Use
postMessage
API for exchanges between the iframe and the host document ↩ -
fetch() global function - Web APIs | MDN and Navigator.sendBeacon() - Web API | MDN ↩
-
Creating and triggering event - Developer guide | MDN and EventTarget: EventTarget() constructor - Web APIs | MDN ↩
-
Use casing rules consistent with existing APIs - Web Platform Design Principles ↩
-
About write good names:
- Lexical grammar - JavaScript | MDN
- Reserved word - Wikipedia
- The Most Common Variable Name - The Lone Coder - PegaSoft Canada
- Good Variable Names
-
Always close open connections before the user navigates away - Back/forward cache ↩