The Script resource allows the app to register custom Javascript to be run in the store or in the checkout page. Also, if the user deletes your app, then he will not have to edit his theme to remove your JavaScript. When an app is uninstalled from a store, all of the scripts the app created are automatically removed along with it.
You should have the following things into consideration:
-
Scripts must be served over HTTPS.
-
You cannot depend of any JavaScript available in the store's theme. Not even jQuery.
-
Another applications may be installed and can include other JavaScript in addition to yours.
-
When we include your script in the store, we will send a
store
parameter with the store id (e.g.<script type="text/javascript" src="https://myapp.com/new.js?store=1234"></script>
). -
Tiendanube layouts have HTML selectors designed so that applications or external agents can be anchored to the design of each store without having to adapt their code based on each layout.
Ideally, your javascript should be inside a closure to avoid any conflict:
(function () {
// Your JavaScript
})();
Use AJAX to load specific configurations for the store. Access your own defined URL with the store ID specified in that URL. Your app will serve those store settings in JSON format, which you can then use in your JavaScript file.
If you are going to use jQuery, you should load it in your JS using jQuery.noConflict
as some stores already have jQuery in their themes. You should not assume the store has a cutting-edge jQuery version.
var loadScript = function (url, callback) {
/* JavaScript that will load the jQuery library on Google's CDN.
We recommend this code: https://snipplr.com/view/18756/loadscript/.
Once the jQuery library is loaded, the callback function will be executed. */
};
var myAppJavaScript = function ($) {
/* Your app's JavaScript here.
$ in this scope references the jQuery object we'll use.
Don't use 'jQuery', or 'jQuery191', here. Use the dollar sign
that was passed as argument.*/
$("body").append("<p>I'm using jQuery version " + $.fn.jquery + "</p>");
};
// For jQuery version 1.7
var target = [1, 7, 0];
var current =
typeof jQuery === "undefined"
? [0, 0, 0]
: $.fn.jquery.split(".").map(function (item) {
return parseInt(item);
});
if (
current[0] < target[0] ||
(current[0] == target[0] && current[1] < target[1])
) {
loadScript(
"//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js",
function () {
var jQuery1101 = jQuery.noConflict(true);
myAppJavaScript(jQuery1101);
}
);
} else {
myAppJavaScript(jQuery);
}
We make your life easier by providing a Javascript object (called LS
) with some common variables.
var LS = {
store : {
id : /* Store's id */,
url : /* Store's URL */
},
cart : {
subtotal : /* Cart's subtotal in cents */,
items : [
/* For every cart item we have */
{
id: /* Product Variant's id */,
name: /* Product Variant's name */,
unit_price: /* Product Variant's price in cents */,
quantity: /* Quantity to be purchased */,
requires_shipping: /* True if product requires physical shipping */
}
],
has_shippable_products : /* True if at least one product requires physical shipping */,
has_non_shippable_products : /* True if at least one product doesn`t require physical shipping */
},
lang : /* Current language's code (e.g. pt_BR) */,
currency : {
code: /* Current currency in ISO 4217 format */,
display_short: /* Currency format string when the currency is not specified.*/,
display_long: /* Currency format string when the currency is specified.*/,
cents_separator: /* Symbol used for separating cents */,
thousands_separator: /* Symbol used for separating thousands (could be blank) */
},
country : /* Current currency in ISO 3166-1 format */,
customer : /* Current customer id or null if there is no logged-in customer */,
theme : {
code: /* Current theme's code */,
name: /* Current theme's name */
}
}
If we are on a Product page we add:
LS.product = {
id : /* Product's id */,
name : /* Product's name */,
tags : /* Array of product's tags */,
requires_shipping : /* True if product requires physical shipping */
};
LS.variants = /* JSON encoded representation of the product variants */;
If we are on a Category page we add:
LS.category = {
id : /* Category's id */,
name : /* Category's name */
};
The checkout's LS object has only some of the properties:
var LS = {
store : {
id : /* Store's id */,
url : /* Store's URL */
},
cart : {
subtotal : /* Cart's subtotal in cents */,
items : [
/* For every cart item we have */
{
id: /* Product Variant's id */,
name: /* Product Variant's name */,
unit_price: /* Product Variant's price in cents */,
quantity: /* Quantity to be purchased */,
}
]
},
customer : /* Current customer id or null if there is no logged-in customer */,
lang : /* Current language's code (e.g. pt_BR) */,
currency : /* Current currency in ISO 4217 format */
}
Note: You cannot access this variable from the JavaScript file where developers can create their own Payment Options.
If we are on the thank you page we add:
LS.order = {
id : /* Order's id */,
number : /* Order's number */,
hash : /* Order's hash */,
created_at : /* Order's creation date */,
coupon : /* Array of coupon codes that apply to this order */,
discount : /* Order's discount in cents */,
total : /* Order's total in cents */,
total_in_usd : /* Order's total in USD in cents */,
gateway : /* Payment Gateway's code */
};
Property | Explanation |
---|---|
id | The unique numeric identifier for the Script |
src | Specifies the location of the Script. Must be HTTPS. |
event | DOM event which triggers the loading of the script. Valid values are onload (default) |
where | A comma-separated list of places where the javascript will run. Valid values are store (default) or checkout |
created_at | Date when the Script was created in ISO 8601 format |
updated_at | Date when the Script was last updated in ISO 8601 format |
Receive a list of all Scripts.
Parameter | Explanation |
---|---|
since_id | Restrict results to after the specified ID |
src | Show Scripts with a given URL |
created_at_min | Show Scripts created after date (ISO 8601 format) |
created_at_max | Show Scripts created before date (ISO 8601 format) |
updated_at_min | Show Scripts last updated after date (ISO 8601 format) |
updated_at_max | Show Scripts last updated before date (ISO 8601 format) |
page | Page to show |
per_page | Amount of results |
fields | Comma-separated list of fields to include in the response |
HTTP/1.1 200 OK
[
{
"created_at": "2013-01-03T09:11:51-03:00",
"event": "onload",
"id": 101,
"src": "https://myapp.com/foo.js",
"updated_at": "2013-03-11T09:14:11-03:00",
"where": "store,checkout"
},
{
"created_at": "2013-04-07T09:11:51-03:00",
"event": "onload",
"id": 5123,
"src": "https://myapp.com/bar.js",
"updated_at": "2013-04-08T11:11:51-03:00",
"where": "store"
},
{
"created_at": "2013-04-08T12:09:48-03:00",
"event": "onload",
"id": 6412,
"src": "https://myapp.com/yet_another_script.js",
"updated_at": "2013-04-08T11:11:53-03:00",
"where": "checkout"
}
]
HTTP/1.1 200 OK
[
{
"created_at": "2013-04-07T09:11:51-03:00",
"event": "onload",
"id": 5123,
"src": "https://myapp.com/foo.js",
"updated_at": "2013-04-08T11:11:51-03:00",
"where": "store"
},
{
"created_at": "2013-04-08T12:09:48-03:00",
"event": "onload",
"id": 6412,
"src": "https://myapp.com/bar.js",
"updated_at": "2013-04-08T11:11:53-03:00",
"where": "checkout"
}
]
Receive a single Script
Parameter | Explanation |
---|---|
fields | Comma-separated list of fields to include in the response |
HTTP/1.1 200 OK
{
"created_at": "2013-01-03T09:11:51-03:00",
"event": "onload",
"id": 101,
"src": "https://myapp.com/foo.js",
"updated_at": "2013-03-11T09:14:11-03:00",
"where": "store,checkout"
}
Create a new Script.
{
"invalid_name": "foobar",
"where": "invalid_where"
}
HTTP/1.1 422 Unprocessable Entity
{
"event": ["can't be blank"],
"src": ["can't be blank"],
"where": ["is not included in the list"]
}
{
"src": "https://myapp.com/new.js",
"event": "onload",
"where": "store"
}
HTTP/1.1 201 Created
{
"created_at": "2013-06-01T15:12:15-03:00",
"event": "onload",
"id": 8901,
"src": "https://myapp.com/new.js",
"updated_at": "2013-06-01T15:12:15-03:00",
"where": "store"
}
To prevent performance issues, we use two different events where it's possible to attach the script, onfirstinteraction
, and onload
.
- onfirstinteraction: The scripts will be loaded and executed after the user's first interaction. A scroll up/down, a mouseclick, or a tap will trigger the event.
This event is intended for functionalities that don't affect the above-the-fold or provide other functionalities that are not needed as soon as possible.
This type of event should be the first choice for most applications.
Some application examples could be chatbots, subscription popups, product wishlists, etc.
- onload: The script will be part of the critical path and will be executed as soon as possible on the page load. Its behavior is equivalent to the
window.onload
event.
In most cases this event should be avoided, unless you need to change some critical components above the fold or collect user-related data like behavior or conversions.
Modify an existing Script
{
"created_at": "2013-04-07T09:11:51-03:00",
"event": "onload",
"id": 5123,
"src": "https://myapp.com/another_bar.js",
"updated_at": "2013-06-01T12:05:34-03:00",
"where": "store"
}
HTTP/1.1 200 OK
{
"created_at": "2013-04-07T09:11:51-03:00",
"event": "onload",
"id": 5123,
"src": "https://myapp.com/another_bar.js",
"updated_at": "2013-06-01T12:11:14-03:00",
"where": "store"
}
Remove a Script
HTTP/1.1 200 OK
{}