Is it possible to modify <script> tags on the fly, before a page is rendered? - shopify

I was wondering if it is possible to modify <script> tags on the fly with the Shopify API?
Scenario:
A page renders some <script> tags.
Before the <script> get rendered, my app adds an attribute to them, so that the tag is rendered with the attribute.
Thanks in advance

No. Your script is taken from Shopify with a GET request where it is inserted into the Liquid rendering pipeline for eventual inclusion in the client's HTML payload. If you want that script to do custom stuff, have it do a callback with an App Proxy which would then make it dynamic.
Read this to learn a lot: https://help.shopify.com/api/sdks/shopify-apps/modifying-online-store/use-javascript-responsibly

A Shopify App with the write_themes scope (see Shopify Documentation) can access and edit Assets and the Theme. Your editing of the Theme could include the modification of a <script> tag to as your put it "add an attribute".
Take into consideration whether the Theme designer hard coded the URL of the script or used liquid tags such as {{ 'example.js' | asset_url | script_tag }} to create the asset URL.

Related

Nuxt add GTM (noscript) to body tag on every page / route

I am trying to implement Google Tag Manager on a Nuxt app and am stuck on how to add the noscript tag to the app on every page / route inside the opening body tag. I tried creating a static script and adding the file through the nuxt config:
{ src: "/scripts/gtm.js", body: true }
which added the file to the body but was throwing errors due to the noscript tag and nested iframe from gtm. Not sure if there is a better way to inject the actual script directly inside the body
<!-- Google Tag Manager (noscript) -->
<noscript><iframe
src="https://www.googletagmanager.com/ns.html?id=GT
M-4BXKY65"
height="0" width="0"
style="display:none;visibility:hidden"></iframe></n
oscript>
<!-- End Google Tag Manager (noscript) -->
#Eike is correct there. Noscript is completely useless in 99.99% of GTM usage cases. It's used when a user has JS off, but unlike what you think, it won't make GTM work with no JS. In fact, only one tag can "fire" in that state and that would be a rarely used custom image tag. Most commonly used for firing pixels.
Yes, noscript implies an iframe and if your app doesn't support them, well then no noscript for you. Really, Nuxt is a front-end rendering framework. Why would you have anything in your <noscript> other than asking the user to enable JS in order to see the site...
The head property in your nuxt.config.js lets you define all the meta data and scripts that appear on each page. It looks like you can add a noscript section for what you need.
This applies to Nuxt v2.
I added the noscript GTM code through layouts/default.vue. Doing that inserts it into body, albeit not completely at the end (which is probably fine). I had to use v-html to avoid hydration mismatch errors ("The client-side rendered virtual DOM tree is not matching server-rendered content.").
<template>
<noscript v-html="iFrameCode" />
</template>
<script>
export default {
data() {
return {
iFrameCode: '<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XYXYXYX" height="0" width="0" style="display: none; visibility: hidden" />',
}
},
}
</script>
What confused me a bit when testing the implementations was the following:
When I had JavaScript on, this is what I saw in Chrome Dev Tools:
But when I tried turning JavaScript off, the code seemed to run fine:

How to integer an oembed javascript tag inside a VueJs component?

I have an "embed" field used by my users for transform a simple link to a rich content link (link with image, title, description, etc.).
Example:
Note: I use this library to get all link information: oscarotero/Embed
As you can see, when you provide an url (a twitter tweet by example), the "code" parameter contain the HTML and script tags to include on my frontend:
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I am so hopelessly in love with #ChucklefishLTD ‘s spooky logo pic.twitter.com/2KtjCNOOUl</p>— Tom Slayed 🔪😱 (#TomJamesSlade) October 12, 2020</blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
The problem is with VueJs and the script tag. When my ajax call is OK, I store all embed informations like that:
this.preview = response.embed
And inside my component, I display the html code with the "v-html" VueJs directive
<div v-if="preview['code']" v-html="preview['code']"></div>
The html is displayed :
The script tag is visible inside the code inspector :
But the script is not loaded :
I have the same problem with all oembed url who provide a javascript tag inside the response.
Note: If I try to load the script directly inside the component, VueJs return this error:
VueCompilerError: Tags with side effect ( and ) are ignored in client component templates
A solution on google is to use the "mounted" event, but it's not compatible with my context.
Because the script I have to load is received from an api and can be different each time depending of the link.
it's bit late but here is an option: The api gives you the possibility to not send the script tag, so you can include it on your own in the html before. Add to the url a omit_script=true and it's gone in the result.
Then you can insert the twitter block. Maybe you have to call twttr.widgets.load() to initialize the tweet.
Edit: Since you're using the plugin, this should be working
$embed = new Embed();
$result = $embed->get('https://www.instagram.com/p/B_C0wheCa4V/');
$result->setSettings([
'oembed:query_parameters' => ['omit_script' => true]
]);
$oembed = $info->getOEmbed();

Vue syntax rendered after page load

I am a newbie in Vue.js. I am currently using Vue.js on top of asp.net core.
I noticed that in 99% time page is served before Vue.js syntax is rendered. How can I prevent this from happening?
For example
When page load first I see
<ol>
<li v-for="u in subscribers">{{ u.name }} - {{u.email}}</li>
</ol>
And then after split of a second I see
<ol>
<li>John - john#domain.com</li>
<li>John1 - joh1n#domain.com</li>
</ol>
Since the template is written inside the page HTML code it will always be shown first by the browser when it’s loading the page. Usually Vue components include a template which is used to render the data and this won’t happen.
You can take the template that is written on the page and add it to the Vue component so it will use it to render, not the contents of the page. The simplest way is to just add the template as a parameter to the Vue component, but later on it may be better to use separate template files, or Single File Components which may take a bit more work.

Big commerce add active class using handlebar

I am using the cornerstone theme and I need an active class for the current navigation. I have used the jQuery and javascript but I want to use the handlebars HTML template engine.
Yes, It is possible to Handlebar.
You can put {{is_active}} in navigation iteration loop in handlebar.
{{#if is_active}}active{{#if}}

problem with django templating system

I'm having a problem with the django templating system.
I have a template with html, css, and js. When I use this template for my site, all of its margins and paddings change, and my template seems to become another template. For example margin 0 auto; seems to become margin 0 0;.
Note: I have a temp.html file and, for example, in the index of my home app, I have a file index.html that contains a {% extends "temp.html" %} tag and other block that they are in temp.html. (ed: ?)
If you need more code, please let me know.
You will need to make use of Django's built-in media hooks and relative URLs:
Django media URLs in CSS files