Add "Frame This Item" Buttons to Your WooCommerce Store

Modified on Sat, 27 Jun at 3:12 PM

This article explains how to add "Frame This Item" buttons to product pages in your WooCommerce store, so customers can open a specific artwork directly in your SimulArt designer, choose a frame, and add the finished piece to their cart.

It combines two SimulArt features you may already be using: the iframe/connect page integration and the bridge page that preloads a remote image into the designer.


How it works

A "Frame This Item" button is not a direct link to the SimulArt designer. It follows a short chain:

Product page button
      │  (link with per-product parameters in the query string)      

Your "Frame Designer" page on WooCommerce
      │  (JavaScript reads the query string and builds the iframe URL)

SimulArt iframe → https://ACCOUNT_URL/bridge?redir=connect_page&...
      │
      ▼
Connect page (customer frames the artwork, then adds it to the WooCommerce cart)

So you build two things: one designer page that hosts the iframe, and a button on each product that links to that page with the right parameters.

Throughout this article, replace ACCOUNT_URL with your own SimulArt subdomain (for example youraccount.framing.studio). Use the same subdomain everywhere.


Prerequisites

Before you start, make sure:

  1. You are on the Framer & Customers plan.
  2. Your SimulArt account is connected to WooCommerce (see Connect to WooCommerce).
  3. Your SimulArt account is installed on a custom subdomain matching your store domain. This is set up by SimulArt — contact support to start the installation, which includes the SSL certificate needed to secure the iframe URLs (see Iframe Integration for WooCommerce).

Step 1 — Create the "Frame Designer" page

This is the page the buttons link to. It loads the SimulArt designer in an iframe and forwards the incoming product parameters to the bridge.

1a. Add the resizer script to the page <head>

This makes the iframe resize to fit its content and defines the myWidth / myHeight values used in the next step. Add it inside the <head></head> of the designer page (in many themes you can do this with a per-page header-scripts option, or a plugin such as a header/footer code manager). Replace ACCOUNT_URL.


<script src="https://ACCOUNT_URL/ext/iframeResizer/iframeResizer.min.js" type="text/javascript"></script>
<script language="javascript">
var myWidth = 0, myHeight = 0;
if (typeof(window.innerWidth) == 'number') {
  myWidth = window.innerWidth;
  myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
  myWidth = document.documentElement.clientWidth;
  myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
  myWidth = document.body.clientWidth;
  myHeight = document.body.clientHeight;
}
</script>


1b. Add the iframe embed to the page body

Add this where you want the designer to appear (in a Custom HTML block, for example). Unlike the standard connect_page embed, this version reads the parameters from the page URL and passes them into the bridge so the chosen artwork preloads. Replace ACCOUNT_URL.


<style>iframe{width:100%}</style>
<iframe id="simulart" scrolling="no" style="border: none; min-height: calc(100vh);"
        onload="iFrameResize({autoResize:true,checkOrigin:false})"
        allowfullscreen allow="fullscreen"></iframe>
<script type="text/javascript">
const params    = new URLSearchParams(window.location.search);
const url        = params.get('imageURL');
const width      = params.get('width');
const height     = params.get('height');
const preset     = params.get('preset');
const price      = params.get('price');
const title      = params.get('title');
const thickness  = params.get('thickness');

document.getElementById("simulart").src =
  "https://ACCOUNT_URL/bridge?redir=connect_page"
  + "&parentWidth="  + myWidth
  + "&parentHeight=" + myHeight
  + "&imageURL="     + encodeURIComponent(url)
  + "&width="        + width
  + "&height="       + height
  + "&preset="       + preset
  + "&price="        + price
  + "&title="        + encodeURIComponent(title)
  + "&thickness="    + thickness;
</script>


Note: Wrapping imageURL and title in encodeURIComponent() prevents broken links when an image URL contains query characters or a title contains spaces or symbols. If you prefer, you can omit it, but encoding is the safer default.

Take note of this page's slug (for example /frame-designer/), you'll point the buttons at it in Step 2.


Step 2 — Add the "Frame This Item" button to products

The button is simply a link to your Frame Designer page with the artwork's parameters in the query string. There are two ways to add it.


Option A — Manual (good for a few products)

Paste a link like this into the product's short description (switch the editor to its HTML/code view). Replace the slug, image URL, and values with the product's own:


<a class="button"
   href="/frame-designer/?width=20&height=16&preset=5&price=195&imageURL=https://yourstore.com/wp-content/uploads/2023/01/artwork.jpg&title=My+Artwork&thickness=0.75">
   FRAME THIS ITEM
</a>

Option B — Dynamic (recommended for many products)

Add a snippet to your child theme's functions.php or a code-snippets plugin. It builds the link automatically for every product and places the button under "Add to cart." Adjust the page slug and the custom-field keys to match your store.


add_action( 'woocommerce_after_add_to_cart_button', 'simulart_frame_this_item_button' );
function simulart_frame_this_item_button() {
    global $product;

    // The slug of the Frame Designer page you built in Step 1.
    $designer_page = '/frame-designer/';

    // Per-product values. Change these meta keys to match your custom fields.
    $width     = get_post_meta( $product->get_id(), 'frame_width', true );
    $height    = get_post_meta( $product->get_id(), 'frame_height', true );
    $preset    = get_post_meta( $product->get_id(), 'frame_preset', true );
    $thickness = get_post_meta( $product->get_id(), 'frame_thickness', true );

    // These come straight from the product.
    $price     = $product->get_price();
    $title     = $product->get_name();
    $image_url = wp_get_attachment_image_url( $product->get_image_id(), 'full' );

    // Don't show the button if there's no image to frame.
    if ( ! $image_url ) {
        return;
    }

    $args = array(
        'width'     => $width,
        'height'    => $height,
        'preset'    => $preset,
        'price'     => $price,
        'imageURL'  => $image_url,
        'title'     => $title,
        'thickness' => $thickness,
    );

    // http_build_query() URL-encodes everything correctly and
    // array_filter() drops any optional values you left empty.
    $url = home_url( $designer_page ) . '?' . http_build_query( array_filter( $args ) );

    echo '<a href="' . esc_url( $url ) . '" class="button simulart-frame-button">FRAME THIS ITEM</a>';
}


Where the values come from: price, title, and imageURL are pulled automatically from the product. width, height, preset, and thickness are read from custom fields you set per product, so you'll want to create those fields (for example with ACF or WooCommerce's built-in custom fields) and fill them in for each artwork. If you'd rather store the artwork's physical size in WooCommerce's native dimension fields, you can swap in $product->get_width() and $product->get_height(), but note those are intended for shipping dimensions.

If your original button lived in a theme template override (commonly a copy of single-product/add-to-cart/simple.php or an edit to content-single-product.php), the snippet above replaces it cleanly and survives theme updates, so you can remove the old template edit once this is in place.


Parameter reference

These are the values the button passes through to the bridge. Required items must be present for the designer to load the artwork.

ParameterRequiredDescription
imageURLYesURL of the remote JPEG image to frame.
widthOptionalPhysical artwork width. When supplied, cropping is disabled and the customer cannot change the image.
heightOptionalPhysical artwork height. Same behaviour as width.
presetOptionalID of the frame preset to preload. Find preset IDs in the link of each preset's Edit Preset button.
priceOptionalPrice of the artwork; added to the frame price.
titleOptionalURL-encoded artwork title.
thicknessOptionalSubject thickness for 3D rendering, in decimal inches (e.g. 0.75, 1.5).

Additional bridge parameters you can add for print-on-demand artwork include widthPix / heightPix (pixel dimensions for the resolution check), royaltiesID, and side (subject edge for 3D rendering). See Load Remote Art Images in SimulArt for the complete list.


Notes and tips

  • Keep one subdomain. Use your real SimulArt subdomain consistently in the <head> script and the iframe embed. Mixing subdomains is a common cause of a blank designer.
  • Custom items are hidden by default. Framed items created by customers are uncategorized and hidden in WooCommerce. Because they can contain personal images, keep them hidden. You can assign them a category under Menu → Settings → Third Party Cart Connection → WooCommerce.
  • Cart links to hidden items. By default the cart shows no link back to a hidden custom item. The Iframe Integration for WooCommerce article explains an optional cart.php edit to restore the link without making the item public.
  • Orders. When customers check out through WooCommerce, the order is saved in WooCommerce, not in your framing studio.
  • More secure parameter passing. If you'd rather not expose parameters in a visible URL, the bridge also accepts them via a POST form. See the form example in Load Remote Art Images in SimulArt.

Related articles

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article