How to use app extensions for a newsletter pop-up in a Shopify app?

Hello,

We recently developed a Shopify application that allows our customers to install a Newsletter subscription pop-up on their online store theme.

We want our app to be visible on the Shopify Store and we have chosen to create a public app.

So we wrote our ad for our app and sent it to Shopify staff for validation. Everything is validated today except one point: we must imperatively use the theme app extensions to fully validate the application.

Indeed we do not use the app extensions to add elements to the client theme and we go directly through the API to make the changes.

THE APPLICATION BEFORE MIGRATION :

During installation we make 3 modifications in the client’s theme using the Shopify API.

  • In Sections:

We create a newsletter-popup.liquid file with all the code necessary for the pop-up to work (this is a section made up of “blocks” - important for the following)

  • In theme.liquid:

We add a tag to add the jquery library at the level of the tag

We add the call to our newsletter-popup.liquid section directly after opening the tag (important place for the pop-up to go over all the elements of the website)

  • Creation of webhooks

Creation of a customers/create webhook - to manage the sending of an email after subscribing to the Newsletter

Creation of an app/uninstalled webhook - to delete application side data

This operation is not the cleanest. Particularly during uninstallation, it is possible that residual code remains in the client’s theme. We have therefore provided within our application a functionality to remove the residual code on the client’s theme.

ISSUE :

However, we must use the theme app extension for the validation of our application. After some tests we come to the following conclusion:

In our opinion, to migrate the pop-up to an app extension we must use an “app embed”. This makes it possible to place the pop-up on top of the tag and to make it pass over the other elements of the site during the navigation.

This is where we get an issue because, as I said earlier, the pop-up is a section that uses schema “blocks” but the “blocks” key is not supported by “app embed”.

So my question is, is this the right way to use app extensions? Should I use the embed app? Or other app extension?

We are really deadlocked and thank you in advance for your response.

For more information, we can also send you part of the Shopify code.

Best regards,

David Rollier

1 Like

I can understand why the app review team asked you to use theme app extensions for this. They offer a much cleaner way to embed functionality like this into a theme, without any need to upload assets into the merchant’s theme folder. The one downside is that they only work with Online Store 2.0-compatible themes, however that is becoming less of an issue as more OS2.0 themes are becoming available and newer merchants are starting to use them.

Learning theme app extensions is a time-consuming adventure, but it is the way of the future and if you go through it, you’ll be sure that your app works well with newer stores over the years ahead. And, it should also reduce your support workload as the install/uninstall process is quite a bit cleaner and doesn’t leave bits of code in the merchant’s theme folder.

It sounds like you’ve already discovered this, but there is a difference between “app blocks” and “app embed blocks”. The former is used to render blocks of liquid code into a theme template, and the latter is used to embed tags into the site without uploading assets into the theme folder.

I would think that you should be able to achieve everything needed for your app using an “app embed block”. Just have your Javascript code dynamically insert the necessary HTML markup after the opening tag. Unless I am missing something and there is some reason that your newsletter popup needs to use Liquid?

First, thank you for your response.

For us, it is necessary to use liquid because we want that our Newsletter pop-up to be fully customizable from the Admin Online Store. Shopify provide lot of functionnalities to easly create website customizable elements and it would be a shame to not use it.

As you can see the following schema there is lot of usefull settings to customize the pop-up and we can can not provide only one code for all of our customers :

{% schema %}
  {
    "name": "Probance POP-UP",
	"settings": [
			{
              "type": "header",
              "content": "Display rules"
            },
			{  
                "type": "select",
                "id": "displaying_mode",
                "label": "Display mode",
                "options": [    
					{      
                        "value": "after-scroll",
                        "label": "After scroll"    
                    },
                    {      
                        "value": "after-delay",
                        "label": "After delay"    
                    },
                    {   
                        "value": "disabled",
                        "label": "Disabled"    
                    },
                    {      
                        "value": "test",
                        "label": "Test mode"    
                    }],
              "default": "disabled",
			  "info": "Select 'Test mode' to customize your pop-up."
            },
		
			{
				"type": "number",
				"id": "days_after_first_display",
				"label": "Days between two displays",
				"default" : 0,
				"info": "Choose '0' to display the pop-up everytime."
				
			},
			{
              "type": "range",
              "id": "displaying_delay",
              "min": 0,
              "max": 30,
              "step": 1,
              "unit": "s",
              "label": "Displaying delay",
              "default": 4
            },
			{
              "type": "range",
              "id": "scroll_offset",
              "min": 0,
              "max": 100,
              "step": 5,
              "unit": "%",
              "label": "Scroll offset",
              "default": 30
            },
			{
              "type": "header",
              "content": "General"
            },
			{
              "type": "color",
              "id": "popup_bg_color",
              "label": "Backgound color",
              "default": "#FFFFFF"
            },
            {
              "type": "range",
              "id": "overlay_opacity",
              "min": 0,
              "max": 100,
              "step": 1,
              "unit": "%",
              "label": "Overlay opacity",
              "default": 25
            },
			{
                    "type": "select",
                    "id": "popup_position",
                    "label": "Position",
					"options": [
                        {
                            "value": "center",
                            "label":"Center"
                        },
                        {
                            "value": "right-top",
                            "label":"Right/Top"
                        },
					    {
                            "value": "right-bottom",
                            "label":"Right/Bottom"
                        },
						{
                            "value": "left-top",
                            "label":"Left/Top"
                        },
						{
                            "value": "left-bottom",
                            "label":"Left/Bottom"
                        }
					],
                    "default": "center"
			},
			{
                "type": "checkbox",
                "id": "popup_rounded",
                "label": "Rounded",
                "default": true
			},
			{  
                "type": "select",
                "id": "form_txt_position",
                "label": "Text position",
                "options": [    
                    {      
                        "value": "left",
                        "label": "Left"    
                    },
                    {   
                        "value": "right",
                        "label": "Right"    
                    },
                    {      
                        "value": "center",
                        "label": "Center"    
                    }],
              "default": "center"
            },
			{
              "type": "header",
              "content": "Inputs"
            },
			{
              "type": "select",
              "id": "input_size",
              "label": "Size",
              "options": [
                {
                	"value": "small",
                	"label":"Small"
                },
                {
                	"value": "medium",
                	"label":"Medium"
                },
                {
                	"value": "large",
                	"label":"Large"
                }
              ],
              "default": "medium"
			},
			{
              "type": "color",
              "id": "input_bg_color",
              "label": "Backgound color",
              "default": "#FFF"
            },
			{
              "type": "color",
              "id": "input_color",
              "label": "Color",
              "default": "#121212"
            },
			{
              "type": "checkbox",
              "id": "input_borderless",
              "label": "Borderless",
              "default": true
            },
			{
              "type": "color",
              "id": "input_border_color",
              "label": "Border color",
              "default": "#000"
            },
			{
              "type": "checkbox",
              "id": "input_rounded",
              "label": "Rounded",
              "default": false
            },
			{
              "type": "checkbox",
              "id": "input_placeholder",
              "label": "Placeholder only",
              "default": true
            },
			{  
                "type": "select",
                "id": "input_txt_position",
                "label": "Text position",
                "options": [    
                    {      
                        "value": "left",
                        "label": "Left"    
                    },
                    {   
                        "value": "right",
                        "label": "Right"    
                    },
                    {      
                        "value": "center",
                        "label": "Center"    
                    }],
              "default": "left"
            },
			{
              "type": "header",
              "content": "Image"
            },
			{  
                "type": "select",
                "id": "img_position",
                "label": "Position",
                "options": [    
                    {      
                        "value": "left",
                        "label": "Left"    
                    },
                    {   
                        "value": "right",
                        "label": "Right"    
                    },
                    {   
                        "value": "top",
                        "label": "Top"    
                    },
                    {   
                        "value": "under-title",
                        "label": "Under title"    
                    },
                    {      
                        "value": "none",
                        "label": "None"    
                    }],
              "default": "none"
            },
			{
              "type": "image_picker",
              "id": "logo",
              "label": "Logo"
			},
			{
              "type": "range",
              "id": "img_size",
              "min": 0,
              "max": 200,
              "step": 5,
              "unit": "%",
              "label": "Size",
              "default": 115,
				"info": "A size over 100% is recommended."
            },
			{
              "type": "checkbox",
              "id": "img_margin",
			  "label": "Margin",
              "default": false
            },
			{
              "type": "header",
              "content": "Icon close"
            },
			{
                    "type": "color",
                    "id": "icon_color",
                    "label": "Color",
                    "default": "#000000"
			}
	],
	"blocks": [
	  {
          "type": "contact_field",
          "name": "Contact Field",
		  "limit": 3,
          "settings": [				
              {
                "type": "checkbox",
                "id": "input_required",
                "label": "Required",
				"default": false
              },
			  {
                "type": "select",
                "id": "input_type",
                "label": "Type",
				"options": [
					{
						"value": "first_name",
						"label":"First name"
					},
					{
						"value": "last_name",
						"label":"Last name"
					},
					{
						"value": "email",
						"label":"Email"
					}					
				],
				"default":"email"
              }
			  
          ]
      	}, 
		{
          "type": "lang",
          "name": "Labels and translation",
		  "limit": 3,
          "settings": [		
			  {
                "type": "select",
                "id": "lang_label",
                "label": "Language",
				"options" : [
					{
						"value": "FR",
						"label":"FR"
					},
					{
						"value": "EN",
						"label":"EN"
					},
					{
						"value": "ES",
						"label":"ES"
					}					
				],
				"default": "FR"
              },
              {
                "type": "header",
                "content": "Text"
              },
			  {
                "type": "html",
                "id": "lang_heading",
                "label": "Heading",
				"default": "

So my question is : using theme app extension, is it possible to create a section with blocks, and that these blocks are only usable by this section ? One of our pop-up block is to manage pop-up’s labels and traslations and it does not make sens to use it for an other section.

Thank you in advance.

David ROLLIER

1 Like

It’s possible to create “app blocks” which are blocks of Liquid that merchants can add to their templates. Each app block has a settings panel with a JSON schema similar to what you posted. One shortcoming is that app block settings don’t support attributes like min, max, and step for integer input fields. They’re a little more simplistic but still pretty useful.

With app blocks you can also include JS and CSS assets that get served to the browser along with the app block. So, basically, the HTML for your block gets output by your Liquid code, and then you can add more style and functionality to it with CSS/JS. All storefronts get the exact same Liquid/CSS/JS code - you can’t customize it on a per-store basis.

Dunno if that answers your question, but it does sound like theme app extensions would be a good fit for your app.

If you want to see theme app extensions in action, you can install the free trial of one of my apps, which are Logolicious and Faqtastic. Both of those allow the editing of content within the app, and placement of an app block using the theme customizer.