<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer> </script>
As you can see in the example above, taken from the official Recaptcha V2 documentation, when the API is loaded it will automatically recover the values "explicit" for
render and "onloadCallback" for
But how does it do that? I was left wondering after I needed to implement a similar functionality myself. The answer is
The MDN documentation for document.currentScript states the following:
It's important to note that this will not reference the <script> element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
What does that mean?
Say you create your own script at
yoursite.com/api/my_api.js and you tell people to include it like this:
<script src="https://yoursite.com/api/my_api.js?widget_color=blue" ></script>
When the script will be loaded and evaluated,
document.currentScript will point to its DOM own node. This means you can do something like this in your code:
let api_script = document.currentNode; let api_script_src = api_script.getAttribute('src');
In that moment,
api_script_srcs value will be
https://yoursite.com/api/my_api.js?widget_color=blue and from here you can recover the value blue for the
It's up to you on how to recover the value. One version would be to use the URLSearchParams object.
let api_script_src_url = new URL(api_script_src), api_url_params = new URLSearchParams(api_script_src_url.search); let widget_color = api_url_params.get('widget_color'); // will return "blue"
Any other options?
If passing that via the API's script URL is not an ok solution for you, an alternative would be to use custom tags. For example:
<script src="https://yoursite.com/api/my_api.js" data-color="blue" ></script>
In this scenario, the code to recover the value will look like this:
let api_script = document.currentNode; let color = api_script.getAttribute('data-color'); // will return 'blue'
This method has the advantage that you do not need to encode and decode the params as URI components.
If you're building a widget and the solution described in this post is helpful, you might also want to check another one of my articles: How to create a web button unaffected by external CSS styles in which I describe how to use Shadow DOM.