App embed extension not showing in dev store

I’m developing a shopify app which includes an app extension to show a widget on a product page. When I run shopify app dev I can see

│ The theme app extension development server is ready.

│ Next steps

│ 1. Install your app in your development store

│ 2. Setup your theme app extension in the host theme

│ 3. Preview your theme app extension at http://127.0.0.1:9293

Clicking on the preview of the theme app extension, shows the product with the widget I developed.

However, then the terminal shows me:

Preview URL: https:/[mystorename].myshopify.com/admin/oauth/redirect_from_cli?client_id=[my_client_id]

GraphiQL URL: http://localhost:3457/graphiql

Now when the app is installed in my dev store using the above link, the product page is missing the widget. When I go to customise my theme, on the default product template go on App embeds, I see the message: “You don’t have any apps with embeds installed. Find apps built for Online Store 2.0 themes on the Shopify App Store.”

What am I missing?

Additional context, when I run shopify app deploy I can see the following below, which suggests the app extension should be present:

╭─ info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Using .env for default values: │
│ │
│ Org: [My Organisation Name] │
│ App:[My App Name] │
│ Include config: Yes │
│ │
│ You can pass --reset to your command to reset your app configuration. │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

? Release a new version of [My App Name]?
:check_mark: Yes, release this new version

Releasing a new app version as part of[My App Name]

[My App Extension Name]│ Running theme check on your Theme app extension…
[My App Extension Name] │
[My App Extension Name] │ Bundling theme extension[My App Extension Name]…

╭─ success ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ New version released to users. │
│ │
│[My App Name]-20 │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Hi @dpplockerbie , such errors are very frustrating when you don’t even know where to start debugging. Lets debug together, please share the embed file code.

Thank you for offering your help @Junaid-Ahmed . Please let me know if I should share any other file contents, these are the files and content within the extension (located in the extensions folder of my app)

shopify.extension.toml:

name = "sonare-widget"
type = "theme_app_extension"

settings_schema.json:

[
	{
	  "name": "General",
	  "settings": [
		{
		  "type": "header",
		  "content": "Settings for Sonare Widget"
		},
		{
		  "type": "text",
		  "id": "widget_title",
		  "label": "Widget Title",
		  "default": "Sonare Widget"
		},
		{
		  "type": "textarea",
		  "id": "widget_description",
		  "label": "Widget Description",
		  "default": "This widget displays additional product information."
		}
	  ]
	}
  ]

sonare-widget/blocks/sonare-widget.liquid

{% if product.metafields.sonare.id %}
  
    

Loading Sonare product details...

  

  
  
{% endif %}
{% schema %}
{
  "name": "Sonare Widget",
  "target": "section",
  "settings": []
}
{% endschema %}

sonare-widget/assets/sonare-widget.js

document.addEventListener("DOMContentLoaded", async () => {
    const widget = document.getElementById("sonare-widget");
    if (!widget) return;

    const sonareId = widget.getAttribute("data-sonare-id");
    if (!sonareId) {
        widget.style.display = "none";
        return;
    }

    try {
        const response = await fetch(`/api/product-details?sonareId=${sonareId}`);
        const product = await response.json();
		console.log('PRODUCT in WIDGET:', product);

        if (!product || !product.name) {
            widget.style.display = "none";
            return;
        }

        widget.innerHTML = `
            
                

                    
                    

                        ### ${product.name}
                        

${product.description}

                    

                

                
                    

**Product Code:** ${product.product_code}

                    

**Brand ID:** ${product.brand_id || "N/A"}

                    

**Country of Origin:** ${product.country_of_origin}

                    

**Last Updated:** ${new Date(product.last_updated).toLocaleDateString()}

                

                
                    

**Environmental Impact:** ${product.environmental_impact}

                    

**Safety Compliance:** ${product.safety_compliance || "N/A"}

                    

**Recycling & Disposal:** ${product.recycling_disposal}

                

                
                    

**Usage Instructions:** ${product.usage_instructions || "N/A"}

                    

**Care Instructions:** ${product.care_instructions}

                

                
                    

**Warranty Service:** 
                        ${product.warranty_service 
                            ? 'Available' 
                            : 'Not Provided'}
                    

                    

**Manufacturer's ID:** ${product.manufacturers_id || "N/A"}

                

                
                    [
                        View on Website
                    ](https://${product.deeplink})
                

            

        `;

    } catch (error) {
        console.error("Failed to load Sonare data", error);
        widget.style.display = "none";
    }
});

sonare-widget/assets/sonare-widget.css

.sonare-widget-container {
    font-family: Arial, sans-serif;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 16px;
    background: #f9f9f9;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    max-width: 100%;
}

.sonare-widget-header {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
}

.sonare-widget-thumbnail {
    width: 60px;
    height: 60px;
    border-radius: 6px;
    margin-right: 12px;
    object-fit: cover;
}

.sonare-widget-title h3 {
    font-size: 18px;
    margin: 0;
}

.sonare-widget-description {
    font-size: 14px;
    color: #555;
    margin: 4px 0 0;
}

.sonare-widget-section {
    padding: 8px 0;
    border-top: 1px solid #e0e0e0;
}

.sonare-widget-section p {
    margin: 4px 0;
    font-size: 14px;
}

.sonare-widget-badge {
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: bold;
}

.sonare-widget-badge.success {
    background: #d4edda;
    color: #155724;
}

.sonare-widget-badge.warning {
    background: #fff3cd;
    color: #856404;
}

.sonare-widget-footer {
    margin-top: 12px;
    text-align: center;
}

.sonare-widget-button {
    display: inline-block;
    background: #007ace;
    color: white;
    padding: 8px 16px;
    border-radius: 6px;
    text-decoration: none;
    font-size: 14px;
    font-weight: bold;
}

.sonare-widget-button:hover {
    background: #005fa3;
}

sonare-widget/locales/en.default.json

{
	"sonare-widget": {
	  "title": "Sonare Widget",
	  "description": "Displays additional product information.",
	  "product_code": "Product Code",
	  "brand_id": "Brand ID",
	  "country_of_origin": "Country of Origin",
	  "last_updated": "Last Updated",
	  "environmental_impact": "Environmental Impact",
	  "safety_compliance": "Safety Compliance",
	  "recycling_disposal": "Recycling & Disposal",
	  "usage_instructions": "Usage Instructions",
	  "care_instructions": "Care Instructions",
	  "warranty_service": "Warranty Service",
	  "manufacturers_id": "Manufacturer's ID",
	  "view_on_website": "View on Website"
	}
  }

I think I may have figured it out. In sonare-widget/blocks/sonare-widget.liquid, change “target”: “section” to “target”: “head” or you can use body as value too depending on your requirement and usage of the app embed.

Refer to this doc for further knowledge. https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#app-embed-blocks

Hi Junaid,

thanks so much

This helped getting the app to show up within App embeds and I can tick a box to enable it.

Unfortunately, even after enabling when I go to the product template itself though, I still can’t seem to add the widget to the product page, it doesn’t show up. As this might be a different issue, I’ve marked your solution as accepted. However, do you by any chance have another pointer that could help me actually add the widget to the products?
I probably won’t be able to test any suggestions before the next weekend, so I might be slow to respond, apologies in advance

Hey, glad that the solution helped.

So the block you had previously could be used as a section/block in your theme customizer on the product page. If you need a block in your app, create a new .liquid file and use the “target”: “section” value. Its possible for an app to have an embed block and a theme block at the same time.

Thanks again!

I don’t need the block in my app, I just need it in the theme customizer. So from my understanding, after looking through the documentation you’ve provided, now I should be able to add the block to the product page with the current setup.
I have my app widget enabled:

But when I try to add a block on the product template, my app does not show up as an option:

And consecutively the widget does not show in the product information section.

However, still when I open the app extension preview directly (i.e. on localhost http://127.0.0.1:9293, rather than through my development store), I can see the widget in the product information section:

Do you have any further ideas what I could be missing? I really appreciate your help.

I’ve figured out my issue - I had a big misunderstanding of the app extension types. I don’t need to both have my app embed showing in the app embeds and it being able to add my app extension as a block, I only need the latter.

Glad that you figured it out. happy coding!