Shoppingate Logo
HomePartnerSell on E-commAbout UsContact UsDevelopers
Documentation
  • Getting started
  • Choosing your path
  • Introduction
    • Introduction
    • Sign up & login
    • Dashboard & analytics
    • Mini-Programs
    • Submit & publish a version
    • App Binding
    • Privacy Settings
    • Allowed URL
    • Users & roles
    • Introduction
    • Install & log in
    • Create a project
    • The workspace
    • Preview & upload
  • app.json config
  • Lifecycle
  • Routing & query
  • Host functions
  • orderPayment
  • Permissions
  • User info
  • Deep links
  • Overview & SDK
  • The wrapper
  • What a page can reach
  • Host functions
  • Permissions
  • Look and feel
  • Testing
  • Authentication
  • Endpoints
  • Webhooks
Web view

Overview & SDK

Wrap a web app you already have in a mini-app and it keeps working, with access to payment, location and the user's profile. This page covers the SDK and the three things that will otherwise cost you an afternoon.

This section is about web pages inside a <web-view>. If you are building screens as mini-app pages instead, read Native mini-app — most of the API advice there does not apply to a page, and vice versa. Not sure? Choosing your path.

The shape of it

A web-view mini-app is a small native shell whose only job is to host your page. The shell is a handful of files; your app stays where it is, served over HTTPS. The page loads the JSSDK, which gives it an ft object of its own, and that is the bridge to the host.

Studio ships a Webview template that gives you the shell. The code below is what the template contains, so you can read it before you generate it — and so you can build the shell by hand if you would rather.

The SDK

Load it in your page. One file, no build step, no package to install.

<!-- Load it in the TOP-LEVEL document of your page. -->
<script src="https://shoppinggate-public.s3.ap-south-1.amazonaws.com/webview-sdk/sg-jssdk-1.4.20.js"></script>

Download: sg-jssdk-1.4.20.js. Vendor it alongside your app if you would rather not depend on the CDN at runtime — the version is pinned in the filename deliberately, so an upstream change cannot alter what your page does.

ft.callNativeAPI — the call that reaches host functions — needs 1.4.1 or later.

Your page's ft is not the mini-app's ft

Both are called ft, which makes this easy to miss. They are different objects with different surfaces, and most confusion in a wrap traces back to assuming they are the same.

Where
What ft gives you
In your page
From the JSSDK. A smaller set: ft.callNativeAPI, ft.getLocation, ft.chooseLocation, ft.chooseImage, ft.request, storage, ft.miniProgram.*, ft.getAppletInfo, ft.complete.
In a native page
The full mini-app runtime — around 45 ft.* APIs. Your shell can call any of them and relay the answer to your page.

That asymmetry is the main thing to plan around, and what a page can reach covers it properly — including how the shell relays the rest.

Knowing you are inside a web view

// `ft` exists only inside a web-view. Opened in a desktop browser there is no ft at
// all, so guard once rather than letting every call throw.
var inWebView = typeof ft !== "undefined";

if (inWebView) {
  ft.miniProgram.getEnv(function (res) {
    console.log("inside a mini-app:", res.miniprogram);
  });

  // Tells the host the page finished loading. REQUIRED if the mini-app sets a web-view
  // load timeout: without it the page is treated as having failed, however well it
  // rendered.
  if (typeof ft.complete === "function") ft.complete();
}

ft.complete() is easy to skip and expensive to skip. If the mini-app sets a web-view load timeout, a page that never calls it is treated as having failed no matter how well it rendered.

It must be the top-level document

The SDK binds its bridge to the top-level document. A page inside an iframe still loads the script and still defines ft, so every method is present and nothing throws — calls just never come back.

// The one failure that looks like success.
//
// A page inside an iframe still loads the SDK and still defines `ft`, so every method is
// present and nothing errors — but the bridge binds to the TOP-LEVEL document, so calls
// simply never come back. You get timeouts, not errors, which sends you looking at the
// host instead of at the frame.
if (window.top !== window.self) {
  console.error("Not the top-level document — the bridge will not bind.");
}
You get timeouts, not errors. That sends you looking at the host, the network, your handlers — anywhere except the frame. If calls hang and nothing logs, check this first. It rules out anything that serves your page inside an app shell or a preview wrapper.

Register the host

Your page's domain must be in the allow list in the developer portal. Until it is, the web-view loads nothing and binderror is the only signal — there is no message on screen.

ft.downloadFile has its own allow list, separate from the web-view one. So your page can load perfectly and a download still fail, which looks like a broken API rather than a missing registration.

localhost works in the simulator only, and needs URL checking switched off. A device cannot reach your laptop and localhost can never be allow-listed — see testing for the tunnel approach.

Next

The wrapper — the shell, file by file. What a page can reach — direct calls, host functions, and the relay. Look and feel — the page-level work that stops it feeling like a website.

Need help? We’re here.

Our team is ready to support you in every step of your experience.

Email Us
[email protected]
Sell With SGContact UsTerms of ServicePrivacy PolicyFAQTravel FAQ
Connect with us
X / TwitterLinkedInInstagramFacebookTiktok

Copyright © Shoppingate 2026

Mada
Visa
Mastercard
Apple Pay
Tamara