Product Genius Docs

Manual placement

Hand-place the Product Genius widget or search bar in theme code when app blocks are not an option.

Prefer app blocks wherever they work

Everything on this page is a fallback. Hand-edited theme code is not managed by the Product Genius app: it does not travel with the app, it is not updated when the app is, it is lost when you replace or reinstall the theme, and it is outside what Product Genius support can fix remotely. Use the AI widget block and the search bar block if your theme offers them at all.

Before editing theme code: duplicate the theme (Online Store → Themes → … → Duplicate) and edit the copy, so you have a one-click way back.

When you would do this

  • Your theme does not support app blocks. Older themes (Liquid templates rather than JSON templates) have no Add block → Apps menu, so the extension's blocks are never offered.
  • You need the widget or bar somewhere a section cannot reach — most commonly a search bar inside a header that does not accept app blocks.

If neither applies, stop here and use the blocks.

The snippets below are the markup the app blocks emit, with the theme-editor plumbing removed. Editing theme code is done in Online Store → Themes → … → Edit code.

The AI widget by hand

The AI widget block's whole body is two elements, and neither depends on being inside an app block. Paste them where the widget should appear:

<div id="pg-app-wrapper"></div>
<script id="pg-app-fetch" src="https://tags.productgenius.io/tag.js?shop={{ shop.permanent_domain }}"></script>

Copy it exactly as written:

  • Keep the ids. pg-app-wrapper is where the widget renders, and the loader script uses element ids as its once-only initialisation guard. Renaming either one can stop the widget loading with no error.
  • Keep {{ shop.permanent_domain }} as a Liquid tag — do not paste your .myshopify.com domain as a literal. The Liquid tag keeps working if your store's domains change, and it is the value the app block itself uses.
  • Include it once per rendered page. A second copy creates a duplicate pg-app-wrapper id, and only one element can receive the widget.

Where to put it

Paste the two elements into the template or section file for the page that should show the widget — for example sections/main-product.liquid for product pages, at the point in the markup where the widget should sit.

This is the closer analogue of the app block: the widget appears on exactly the pages whose files you edited, in exactly the position you chose.

The search bar by hand

The search bar is harder to hand-place than the widget, because the app block relies on two things a theme file does not get for free: the theme editor's per-block settings, and the stylesheet the extension attaches to the block.

Check the container selector first

The live bar mounts into a container matching the selector in your store's Product Genius configuration — for the app block, that is .pg-search-mount. A hand-placed container must carry the same class, and your store's configuration must be pointing at it. Confirm this with your Product Genius contact before you start; otherwise you will hand-place markup that never gets replaced by the live bar.

Option 1: mount container only

The smallest possible version is the container the live bar looks for:

<div class="pg-search-mount"></div>

Nothing to style, nothing to copy. The trade-off is that there is no search field at all until the Product Genius bundle mounts — no loading state and no working fallback if it never does. Whether the live bar mounts into an empty container is a property of your store's Product Genius configuration rather than of this markup, so verify it on a real storefront page before shipping.

Option 2: reproduce the skeleton

To keep the app block's behavior — a working native search that the live bar replaces — reproduce the block's markup with your chosen values written in directly. This is the Full bar layout:

{%- assign pg_search_action = routes.search_url | default: '/search' -%}
<div class="pg-search-mount"
     style="max-width: 320px; --pg-skeleton-size: 38px; --pg-compact-expanded-width: 320px; --pg-skeleton-radius: 0px;">
  <form class="pg-search-skeleton" role="search" action="{{ pg_search_action }}" method="get">
    <span class="pg-search-skeleton__icon" aria-hidden="true">
      <svg viewBox="0 0 24 24" fill="none" width="16" height="16">
        <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
        <path d="M21 21l-4.35-4.35" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
      </svg>
    </span>
    <input class="pg-search-skeleton__input" type="search" name="q"
           placeholder="Search" aria-label="Search" autocomplete="off"/>
    <span class="pg-search-skeleton__shimmer" aria-hidden="true"></span>
  </form>
</div>

For the Icon only layout, add the pg-search-mount--compact class to the container and replace the form with a link to the same URL, dropping the input:

{%- assign pg_search_action = routes.search_url | default: '/search' -%}
<div class="pg-search-mount pg-search-mount--compact"
     style="--pg-skeleton-size: 38px; --pg-compact-expanded-width: 320px; --pg-skeleton-radius: 0px;">
  <a class="pg-search-skeleton" href="{{ pg_search_action }}" aria-label="Search">
    <span class="pg-search-skeleton__icon" aria-hidden="true">
      <svg viewBox="0 0 24 24" fill="none" width="16" height="16">
        <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
        <path d="M21 21l-4.35-4.35" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
      </svg>
    </span>
    <span class="pg-search-skeleton__shimmer" aria-hidden="true"></span>
  </a>
</div>

Notes on the differences from the app block:

  • Settings become literal values. The block reads block.settings and writes them into a {% style %} block keyed on a per-instance id. With no block context, put the same custom properties in an inline style attribute — inline declarations outrank the stylesheet's class-level defaults, so they behave the same way. The values above are the block's defaults: --pg-skeleton-size is Height (38 px), --pg-skeleton-radius is Corner radius, max-width and --pg-compact-expanded-width are Max width (320 px). Add --pg-skeleton-bg, --pg-skeleton-border, --pg-skeleton-color, --pg-skeleton-placeholder-color, and --pg-skeleton-icon-color if you need colors other than the defaults.
  • block.shopify_attributes is gone. The block emits it so the theme editor can link the rendered element to its entry in the sidebar. It has no effect on the storefront, so hand-placed markup omits it.
  • The placeholder and the accessible label are separate strings. The block derives the aria-label from the placeholder setting and falls back to the theme's translated search.label. Written by hand, set both explicitly, as above.

The stylesheet

The skeleton in Option 2 is unstyled without pg-search.css. That file is an asset of the app extension, and theme code cannot reference it — asset_url in your theme resolves against your own theme's assets/ folder, not the extension's. So:

  1. Ask your Product Genius contact for the current pg-search.css.

  2. Add it to your theme as assets/pg-search.css.

  3. Reference it from layout/theme.liquid:

    {{ 'pg-search.css' | asset_url | stylesheet_tag }}

Your copy is a snapshot. If Product Genius changes the stylesheet, the app block picks the change up automatically and your copy does not — which is the core reason to prefer the block.

Also worth knowing

The class names in this markup (pg-search-mount, pg-search-skeleton, and its __icon / __input / __shimmer parts) and the data-pg-search-ready attribute the bundle sets on the container to hide the skeleton are the contract between the stylesheet and the bundle. Do not rename them, and do not set data-pg-search-ready yourself — the bundle owns it, and setting it early hides your fallback while there is nothing to replace it.

Removing hand-placed code

Deleting a block in the theme editor is complete: nothing remains. Hand-placed code has to be removed the same way it was added — delete the markup from every file you edited, plus the stylesheet reference and assets/pg-search.css if you added them. Uninstalling the Product Genius app does not remove it, which leaves a script tag pointing at a service your store no longer uses.

How is this guide?

On this page