Mutation: How to add script tag to shop immediately when app is installed? (Node/React/GraphQL App)

Mutation: How to add script tag to shop immediately when app is installed? (Node/React/GraphQL App)

oneezy
Shopify Partner
15 1 5

I'm trying to add a custom <script> tag to the shop immediately when my app is installed but I'm having a hard time figuring out how. This simple task has proven quite difficult for me, being that this is my first Shopify React app.

 

My goals are:

1. Add custom script to the shop immediately when app is installed w/ scriptTagCreate

2. Use GraphQL mutations scriptTagCreate and scriptTagDelete w/ Shopify's Polaris's <SettingToggle> component

  • if SettingToggle enabled = scriptTagCreate
  • if SettingToggle disabled = scriptTagDelete

Screenshot_2019-12-21 oneezy ~ Add Script Tags ~ Shopify.png

 

Can anyone point me in the right direction? Possibly send me some example code of what others have done?

 

I've built out all of my GraphQL queries and mutations w/ scriptTagCreate and scriptTagDelete already. Just need to figure out how to React them in..

 

Thanks for the help in advance! 😃

 

const QUERY_SCRIPTTAGS = gql`
query {
  scriptTags(first: 5 ){
    edges {
      node {
        id
        src
        displayScope
      }
    }
  }
}`;


const WRITE_SCRIPTTAGS = gql`
mutation scriptTagCreate($input: ScriptTagInput!) {
  scriptTagCreate(input: $input) {
    userErrors {
      field
      message
    }
    scriptTag {
      src
      displayScope
    }
  }
}`;

/***********************************************************************************
{
  "input": {
    "src": "https://raw.githack.com/oneezy/add-script-tags/master/pages/script.js", 
    "displayScope": "ONLINE_STORE" 
  }
}
************************************************************************************/

const DELETE_SCRIPTTAGS = gql`
mutation scriptTagDelete($id: ID!) {
  scriptTagDelete(id: $id) {
    deletedScriptTagId
    userErrors {
      field
      message
    }
  }
}`;

/***********************************************************************************
{
  "id": "gid://shopify/ScriptTag/110762885208"
}
************************************************************************************/

 

Replies 12 (12)

hassain
Shopify Staff (Retired)
624 104 188

Hey @oneezy 

 

Have you had a chance to look at this tutorial? --> https://developers.shopify.com/tutorials/build-a-shopify-app-with-node-and-react . It goes over how to build a Shopify app using Node.JS and React, and specifically provides an example on how you can make GraphQL queries and mutations through your app.

 

In short it recommends that you use a library like Apollo to build queries and mutations into your app. The Apollo client and its React components were designed to let you quickly build a React UI that fetches data with GraphQL. Apollo’s components handle complexities like storing low-level networking details and maintaining a local cache when working with an API. https://developers.shopify.com/tutorials/build-a-shopify-app-with-node-and-react/fetch-data-with-apo...

 

 

To learn more visit the Shopify Help Center or the Community Blog.

oneezy
Shopify Partner
15 1 5

yes i've taken that tutorial. I actually ended up hiring a developer to help me on Fiverr.

sohail9689
Tourist
3 0 5

could you please help me out. I'm also at the same point.

LucasFranson
Tourist
4 0 0

Guys, try use a script like this:

jQuery(document).ready(function() {	
		$('body').prepend('<div class="header" id="myHeader"><h1> teste </h1></div>');
		$('head').prepend('<style>.header { padding: 10px 16px; background: #555; color: #f1f1f1; } .content { padding: 16px; } .sticky { position: fixed; top: 0; width: 100%} .sticky + .content { padding-top: 102px; }</style>');

		var header = document.getElementById("myHeader");
		var sticky = header.offsetTop;

		window.onscroll = function() { 
			if (window.pageYOffset > sticky) {
				header.classList.add("sticky");
			} else {
				header.classList.remove("sticky");
			}
		};
  
});


Maybe this will work. Try follow the mutation part in the tutorial with this code that a sent and I hope that works to you.

Best regards Lucas

diego_ezfy
Shopify Partner
2969 571 906

 


@oneezy wrote:

yes i've taken that tutorial. I actually ended up hiring a developer to help me on Fiverr.


Did you need to setup a database like MongoDB to toggle it? Or was just localstorage sufficient?

funnycat
Tourist
3 0 7

I'm having the same issue - do you have any code/examples you could share for how you got it to work? I'm finding the docs linked to be far too sparse. 

insane85
Visitor
1 0 2

Hello there,

i have the similar problem, too. I am new at react and i dont know how to use it on the right way, maybe some codes or some apps on github will help me, too.

Sweetsensej
Shopify Partner
7 0 3

So far I have confirmed that you can either do it via scriptTag mutation or REST API. 

In the tutorial, they only make a POST request to create a billing plan with graphQL. 

How does that apply to creating a POST request and creating scriptTag. Once the scriptTag is created how does one use that scriptTag to actually display it on the store-front when react Component state changes. You would need to have something like Redux on the front-end, no?  

SHOPIFY, please STEP UP on this part as there is not enough documentation to learn how to do it. 

Confirmation from stackoverflow about the ways you can inject js script
https://stackoverflow.com/questions/63376209/how-to-communicate-with-shopify-storefront-and-add-js-s...

Tutorial that is mentioned above that DOES NOT cover adding JS script to store-front and explaining how to turn off the script if react-component state changes. We would APPRECIATE if such a tutorial was there! Thank you 
https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-react/charge-a-fee-using-the-billing...

Scarce example of how creating ScriptTag looks like. BUT HOW SHOULD I APPLY THIS INFO? Where should I input this info? 

https://shopify.dev/docs/admin-api/rest/reference/online-store/scripttag#create

 

 

I have spoken to Shopify Reps and they sent me here, to community.shopify. But it seems nobody knows is able to JUST list the steps on how each part talks to each other. 

Thank you to all who would like to spend some time on this thread and help out fellow beginner developers.  

 

UPDATE THAT COULD HELP YOU:

HOW TO CREATE A MUTATION IN GRAPHQL - 
https://graphql.org/graphql-js/mutations-and-input-types/ 


Here how to create a scriptTag mutation in GraphQL: 

https://community.shopify.com/c/Shopify-APIs-SDKs/GraphQL-error-scriptTagCreate-access-denied/td-p/8...

funnycat
Tourist
3 0 7

Agreed - I really think there needs to be better documentation on this. I was able to get it to work so I'll share here in case it helps someone else:

Some things about ScriptTags that weren't obvious to me but I think Shopify assumes is clear:

  • They're global - so you only need to add them once and then have logic in the script tag that displays what you need to for a given page
  • You can't make API calls to your server directly from them, you have to set up an online store App Proxy through the Shopify settings 

 

Here's my code, built off of the sample app from Shopify that inject a ScriptTag. I would prefer to do it from server.js but couldn't get that working. This is probably not the cleanest way to do it, but it works: 

 

import { EmptyState, Layout, Page } from '@shopify/polaris';
import { ResourcePicker, TitleBar } from '@shopify/app-bridge-react';
import store from 'store-js';
import ResourceListWithProducts from '../components/ResourceList';
import gql from 'graphql-tag';
import { Mutation } from 'react-apollo';
const img = 'https://cdn.shopify.com/s/files/1/0757/9955/files/empty-state.svg';
const CREATE_SCRIPTTAG = gql`
  mutation scriptTagCreate($input: ScriptTagInput!){
      scriptTagCreate(input: $input) {
        scriptTag {
          id
        }
        userErrors {
          field
          message
        }
      }
  }`;
class Index extends React.Component {
  state = { open: false };
  render() {
    const emptyState = !store.get('ids');
    let installScriptTag = !store.get('scripttag');
    const productPageScriptTagInput = {
      src: 'https://raw.githack.com/funnycat/test/master/productPageScriptTag.js', 
      displayScope: 'ONLINE_STORE',
    };
    return (
    	<Mutation mutation={CREATE_SCRIPTTAG}>
  {createScriptTag => 
      <Page>
        <TitleBar
          title="Sample App"
          primaryAction={{
          content: 'Select products',
          onAction: () => this.setState({ open: true }),
        }} />
        <ResourcePicker
          resourceType="Product"
          showVariants={false}
          open={this.state.open}
          onSelection={(resources) => {    
	          	const idsFromResources = resources.selection.map((product) => product.id);
			    this.setState({ open: false });
			    store.set('ids', idsFromResources);
			    if(installScriptTag){
				    const sc1 = createScriptTag({variables: { input: productPageScriptTagInput},});
				    store.set('productscripttag', sc1);
				    installScriptTag = false
				}
			}}
          onCancel={() => this.setState({ open: false })}
        />
        {emptyState ? (
          <Layout>
            <EmptyState
              heading="Discount your products temporarily"
              action={{
                content: 'Select products',
                onAction: () => this.setState({ open: true }),
              }}
              image={img}
            >
              <p>Select products to change their price temporarily.</p>
            </EmptyState>
          </Layout>
        ) : (
            <ResourceListWithProducts />
          )}
      </Page>
        }
		</Mutation>
    );
  }
  handleSelection = (resources) => {
    const idsFromResources = resources.selection.map((product) => product.id);
    this.setState({ open: false });
    store.set('ids', idsFromResources);
    createScriptTag;
  };
}
export default Index;

 

 

You can also see the javascript for the script tag here: https://raw.githack.com/funnycat/test/master/productPageScriptTag.js

You can see the "requestPath" is how I'm reaching my own APIs through the app proxy. Hope this helps someone save many hours haha. 

Sweetsensej
Shopify Partner
7 0 3

Hey Funnycat! 

 

Thanks for a great answer and sharing your code with us. 

Could you show exactly on your store-front what is this code doing? 

Would you be able to walk me through how could I inject this code into product.template.liquid on app install? 

funnycat
Tourist
3 0 7

Hello! 

My ScriptTag code does something like the following:

  • Get the product slug from the URL
  • Use it to make a call to my app's APIs to get settings for that product 
  • Use the settings for that product to replace the checkout button 

Since my app is still very close to the app in this tutorial: https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-react - you could basically clone the tutorial, then add the code I posted into index.js and replace the link with the link to your linked code. It's not exactly doing the injection on app install (I couldn't get that working) but it checks to see if it's ever been done, and does it once when the user selects products. 

Hope this helps!

hashcode_io
Shopify Partner
115 3 13

@funnycat    i can see the shopify app tutorial link has been changed can you suggest the right tutorial or guide. 

Shopify Team @ Conversios System
Please confirm its success with a like or marking it as a solution!
Google analytics 4
SST - Server-side tagging solution.
#martech#GA4 #GTM #ownGTM #SST #ServerSideTagging