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

oneezy
Excursionist
14 1 4

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"
}
************************************************************************************/

 

0 Likes
hassain
Shopify Staff (Retired)
Shopify Staff (Retired)
623 104 146

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...

 

 

Hassain | Developer Support Specialist @ Shopify
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Click Accept as Solution 

0 Likes
oneezy
Excursionist
14 1 4

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

0 Likes
sohail9689
Tourist
3 0 3

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

0 Likes

 


@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?

◦ Product page slider & thumbnails with swiping for free themes: Minimal | Debut | Brooklyn | Supply
◦ Replace apps with simple copy/paste code snippets. Examples clicking here.
0 Likes
funnycat
Tourist
3 0 4

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
New Member
1 0 1

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 2

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 4

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.