Guide to Page Extensions

A page extension is a full page, customisable element that's added to the user's live site. It can appear in the main navigation menu and behaves just like any other page. 

It can have internal pages, each with its own URL – so it’s ideal for apps that use deep linking (like a blog, forum, or ecommerce store).

In this article we'll tell you about all the things to keep in mind when developing a page extension to help you deliver the best possible experience for users.

Things to know before getting started

Here's some useful things to know about a page extension:

  • Users discover your app in the App Market and then add it to their website.
  • Users have to accept necessary permission/s for your app when they add it.
  • Users can add your page extension once to their website (if needed, you can allow users to add the extension more than once).
  • Users can adjust the size of a page extension.
  • A page extension is added and customized by the Wix user, but is used by the site visitors.
  • Deleting the page extension will revoke the app permission/s.

Architecture

A page extension is made up of two parts:

  • The page iframe: the page’s content is provided as an iframe embedded in a Wix website by the user, and is displayed in both the Wix Editor and the published website.
  • The App Settings iframe: this allows users to register, customize, and configure the page extension for their website. The App Settings iframe is embedded in the Wix Editor and is used only by the user.

Note:

Both of these will need to contain our JavaScript SDK, or else they won't load. Read more about our SDK here.

When a user adds your app, we’ll generate a unique ID for your app for this specific site – this is the App Instance ID. You should use this to link your app to this site. 

This ID is sent to you as part of the App Instance query parameter, which is a signed parameter that allows you to identify the website and the Wix user, and verify that the calling party is indeed Wix. 

All of your app’s endpoints will have the same App Instance ID, so each request sent to the page endpoint and to the App Settings endpoint includes the same App Instance ID in the iframe URL.

App Settings panel

To build a page extension, you'll need to create an App Settings panel. Here are some things you should do to create an optimal App Settings experience:

Update the app with the user's changes

When users change a setting in your app, update the app right away in the Wix Editor – but don’t change the app on the live site until the user publishes the site. Here’s how:

  1. Store two sets of data: Store both the data that’s visible in the Wix Editor and App Settings panel, and the data in the live site.
  2. Update the app in the Wix Editor immediately: Show the app with these latest changes in the Wix Editor (including the App Settings panel). Read below on how to do this.
  • If the user doesn’t save these changes, go back to the previous settings. Listen for the SITE\_SAVED event in the addEventListener method. If the user doesn’t save the site, discard the latest changes and go back to the previous settings the next time we call your app endpoint.
  • Wait for the user to publish the site before updating the app in the live site. Listen for the SITE\_PUBLISHED event in the addEventListener method. When SITE\_PUBLISHED is issued, update the app in the live site.

Update your app's settings

When users change your app’s settings, here’s how to update your app right away in the Wix Editor:

1. Detect changes that the user makes in the App Settings panel: Use the onChange or onClick function. 2. Update your database/backend server immediately 3. Show the changes in your app: for a better user experience, don’t refresh your app – here’s what to do instead:

  1. In the App Settings panel, use triggerSettingsUpdatedEvent to send an update event to the extension.
  2. In the extension itself, use addEventListener and listen for the SETTINGS\_UPDATED event.
  3. Update the app with the new settings.

Support multiple pages

Users can only add a page app once from the App Market. If users want to add secondary pages to the main page extension, it's possible for them to add them directly from your App Settings panel. For example, an ecommerce app may want to allow users to set up a few stores on their site.

Here's how to support multiple page extensions in a site:

  1. Tell us which secondary page/s you want this enabled for: get in touch and we'll sort this for you.
  2. Allow users to add your page extension again: use the addComponent method in your App Settings panel.
  3. To distinguish between the page extensions, use the compId parameter: this parameter is a unique string that identifies the extension, specified in the endpoint URL.
  4. Link each page extension to its own settings: this allows users to customize each page differently, so that a change to the settings in one extension won’t affect the other page extensions in the site.

Note:

Use the getOrigCompId method to identify the page extension that opened the App Settings panel – this returns the compId of the page, so you can open the right settings panel.

Page size

Follow our UI/UX guidelines for your page extension’s size:

  • Width: the default width of the page extension is 980px, just like every other page in the site. When we call your widget endpoint, we’ll include the page’s width in the endpoint URL.
  • Height: you’ll need to adjust the height according to the content on the page. Use the setHeight SDK method and don’t add scroll bars.

Deep linking

A page extension supports deep linking for its internal pages. There are two supported forms of deep linking you can use: server-side rendering and AJAX rendering. You can also combine the two.

Note:

The section-url parameter referenced in this document refers to the page iframe URL.

AJAX rendering

For AJAX apps, deep linking enables your app to update the content of your iframe without refreshing the whole iframe. 

Your page extension changes its state using JavaScript and AJAX methods. After the page extension changes its state, it notifies the host website using the Wix.pushState() JavaScript method. This call will not reload your iframe. Wix will update the top window App-state part of the page URL, allowing it to be shared or copied and pasted to other locations.

Example: 

If the browser is showing this URL: https://site.domain.com/page-title/App-state-1 when you call the method: pushState(“App-state-2”) the browser URL will change to https://site.domain.com/page-title/App-state-2, but your page iframe will not reload. 

When a user shares or copies and pastes a link, and there’s a resultant request to render a page with a deep-linked URL state of your page extension, Wix will call your page with the internal state as part of the iframe’s URL in the App-state path variable. You should load your page extension at the intended internal page state.

Example:

When a user clicks on a link with a URL such as: https://site.domain.com/page-title/App-state Wix will reload the page iframe using the URL: https://your-section-endpoint-url/App-state?rest-of-the-parameters

Server-side rendering

Deep linking for server-side apps enables your page extension to render different pages depending on the App-state path of your iframe. 

A page extension supports deep linking using this flow:

  1. Render links in your page extension using the section-url and target parameters (both parameters are passed to your app as part of the page iframe URL). section-url should be the base URL for your internal pages, and the target parameter should be used as the target attribute of anchor tags.
  2. When viewing a page extension on a published website, Wix will pass the section-url as the URL of the page extension website page, and the target as \_top.
  3. When a user clicks on such a link, the top window URL changes to the new URL. Full-page reload will not occur. The new URL can be shared or copied and pasted to other locations.
  4. Wix will catch the history-changed event and will update the page iframe URL, setting the App-state path parameter to the value “Appended by the App” to the section-url parameter.
  5. When a user shares or copies and pastes a link, and there’s a resultant request to render a page with a deep-linked URL state of your page extension, Wix will call your page with the internal state as part of the iframe’s URL in the App-state path variable. You should load your page extension at the intended internal page state.

Example

Assume that there is a Wix website with the domain www.domain.com, which has a page extension on the page www.domain.com/page-title. Also assume that the page endpoint is www.App.com.

  1. The following URL will open the page iframe:
Copy
1
www.App.com/?instance=XXX&section-url=www.domain.com/page-title/&target=_top&....

Note:

The section-url parameter will be URL encoded. This example is not encoded for readability purposes.

  1. When you render a link to an internal page, such as my-internal-page, you should render:
Copy
1
href="http://www.domain.com/page-title/my-internal-page" target="_top">...</a>
  1. When a user clicks on this link, the browser top window URL changes:
Copy
1
http://www.domain.com/App/my-internal-page
  1. Wix catches the change in the top browser window URL and updates the page iframe URL:
Copy
1
www.App.com/my-internal-page?instance=XXX&section-url=www.domain.com/page-title/&target=_top&...

Using this flow, your page extension will reload in the iframe with the new URL.

SEO

Page apps must be fully optimized for search engine crawlers, to improve SEO for your users. There are two main steps to optimize your app:

  1. Optimize the app itself in the live site: As search engines like Google can crawl JavaScript, make sure the app itself is fully optimized for SEO.
  2. Develop an SEO endpoint: As not all search engines crawl JavaScript, we’ll call your SEO endpoint when a search engine requests the SEO version of your app

Optimize your app in the live site

Follow these dos and don’ts to optimize your app for search engines. 

Do:

  • Add alt text and src to images: that way, these attributes are easily readable in the DOM.
Copy
1
<img src="myAppImage.png" alt="This is an image of my app! ">
  • Use absolute, schemeless links and add the href attribute: this is the full URL without the protocol. For example:
Copy
1
<a href="//www.myApp.com">Check out this page!</a>
  • Add rel=”noreferrer” for links to other site pages: have links that go to other pages in the user’s site, like the homepage? Set the rel attribute value to “noreferrer” for links that go to these pages – excluding links to your app’s internal pages. (This ensures that users don’t see your app’s iframe URL as a referrer in Google Analytics.)
Copy
1
<a rel="noreferrer" href="//www.site.com/">Check out this page!</a>

Manage internal pages in your app the right way:

  1. Use deep linking to link to internal pages.
  2. Return a 404 error for deleted internal pages.
  3. Set a title and description for internal pages using the setPageMetaData SDK method. These values must match what’s in your SEO endpoint.
  • Title: insert the name of the internal page into the page title. For example, the page name in an eCommerce app would be the name of the product, e.g., ‘Green Hoodie’.
  • Description: we recommend using the first 160 characters from the page content, or allowing users to customize the description.
  • Use h1 only for internal pages: For the app’s main page, don’t use h1. Use h2, h3, and so on, according to your app’s hierarchy.

Don't:

  • Add a noindex meta tag: Google can crawl JavaScript, so don’t block search engines from crawling JavaScript in your app’s iframe.
  • In the robots.txt file don’t block anything that’s needed for the page to load: Contact us if you think something should be blocked.

Develop an SEO endpoint

Create a separate HTML file for the SEO endpoint. Your SEO endpoint should be an “HTML snapshot” – a  stripped down version of your app that has all the static HTML content visible on the user’s site, and none of the JavaScript or dynamic functionality.

Here are some important things to keep in mind when creating your SEO endpoint:

  • For your app’s main page, only include the tag. Include visible content only – headings, lists, images, etc.
  • Don't include or tags in the element: leave this data for the user to define.
  • Don't include
  • Make sure the elements match the app itself. For example, the heading structure, alt text for images, etc.
  • Link to your app’s internal pages: deep link to internal pages, and use absolute, schemeless links. For example:
Copy
1
<a href="//www.site.com/product-page/green-hoodie"> Green Hoodie </a>
  • For internal pages, include both the and : unlike the app’s main page, you should include tags in the element for internal pages:
  1. Add the title and description you already set in the app via the setPageMetaData SDK method.
  2. Add Open Graph tags for social media (title, type, URL and image).
Copy
1
//Example of an internal product page in an eComm app
2
<head>
3
<title> Page/Product Name</title>
4
<meta name="description" content="Page/Product Description">
5
<meta property="og:title" content="Page/Product Name" />
6
<meta property="og:type" content="website" />
7
<meta property="og:url" content="//www.site.com/product1/" />
8
<meta property="og:image" content="//www.site.com/product1/myProduct.png"/>
9
</head>
  • Don’t display content in the SEO endpoint that isn’t visible in the app: search engines consider this to be bad practice, since it’s usually done to manipulate SEO ranking. Search engines detect this, and may remove suspect pages or the entire site from their index. E.g., if your app doesn’t include marketing text like “powered by MyCompany” – then don’t include it in the SEO version.
  • Support SEO in other languages: after you render the HTML for your SEO view, include an additional header in your HTTP response: Content-Type: “text/html;charset=UTF-8”.
  • Make sure your endpoint is up, publicly accessible, up-to-date, and fast:
    • Define a publicly accessible URL (don’t use a localhost hostname).
    • Keep the error rate low – otherwise, we’ll turn off your SEO endpoint.
    • Update the content dynamically so that it reflects the current content in the app.
    • Load the endpoint within 4 seconds.

Main page extension examples

App HTML

Copy
1
//App HTML page includes JS
2
<html>
3
<body>
4
<h2>HEADING</h2>
5
<p id="divid"></p>
6
7
<script>
8
var car_name = ["Mazda", "Volvo", "Nissan", "Ford", "Skoda", "Audi"];
9
var string = "";
10
var i;
11
for (i = 0; i < car_name.length; i++) {
12
string += car_name[i] + "<br>";
13
}
14
document.getElementById("divid").innerHTML = string;
15
</script>
16
17
</body>
18
</html>

SEO Endpoint

Copy
1
//Static HTML code that displays the visible content
2
<body>
3
<h2>HEADING</h2>
4
<p id="divid">
5
Mazda<br>
6
Volvo<br>
7
Nissan<br>
8
Ford<br>
9
Skoda<br>
10
Audi<br>
11
</p>
12
</body>

Internal page extension examples

App HTML

Copy
1
//App HTML page includes JS
2
<html>
3
<head>
4
<title>INTERNAL PAGE TITLE </title>
5
<meta name="description" content="INTERNAL PAGE DESCRIPTION"/>
6
</head>
7
<body>
8
<h2>HEADING</h2>
9
<p id="divid"></p>
10
11
<script>
12
var car_name = ["Mazda", "Volvo", "Nissan", "Ford", "Skoda", "Audi"];
13
var string = "";
14
var i;
15
for (i = 0; i < car_name.length; i++) {
16
string += car_name[i] + "<br>";
17
}
18
document.getElementById("divid").innerHTML = string;
19
</script>
20
21
</body>
22
</html>

SEO Endpoint

Copy
1
//Static HTML code that displays the visible content
2
<html>
3
<body>
4
<head>
5
<title>INTERNAL PAGE TITLE </title>
6
<meta name="description" content="INTERNAL PAGE DESCRIPTION"/>
7
</head>
8
9
<h2>HEADING</h2>
10
<p id="divid">
11
Mazda<br>
12
Volvo<br>
13
Nissan<br>
14
Ford<br>
15
Skoda<br>
16
Audi<br>
17
</p>
18
19
</body>
20
</html>

Check your app's SEO view

You can see what your app looks like to a search engine crawler – whether or not you developed a dedicated SEO endpoint by accessing the site / page with a Googlebot.

 Here’s how to do it in Google Chrome:

  • Right click anywhere on your page and click Inspect.
  • Click Menu in the top right > More tools > Network conditions
  • Under 'User agent' uncheck 'Use browser default'
  • Select a Googlebot from the dropdown or paste one into the Custom field

For browsers like Edge, Firefox and Safari, check out this article.

Mobile endpoint

Create a mobile endpoint for your app so that it works well on mobile devices.  This endpoint should have the same functionality as your web app – except for these differences:

  • The mobile endpoint should be created according to our mobile UI/UX guidelines.
  • The app width will be automatically set to 280px. The height is unlimited, and you will be able to modify it using the setHeight method in our JavaScript SDK. However, we recommend keeping the mobile view short, and providing a link or pagination to additional data.

Endpoint URLs

URL Requirements

  • HTTPS: Wix uses HTTPS to maintain high security standards. All URLs, whether they are OAuth or iframe need to use HTTPS throughout the development process, otherwise they won't load on the Wix system.
  • Localhost or ngrok: you can use both of these during development, but you'll need to change the URL before you submit your app for review. As localhost and ngrok run on your local machine, our team won't be able to check them when reviewing your app.

Page request URL template

Copy
1
endpoint]/[app-state]?instance=[signed-instance-data]&section-url=[section-url]&target=[target]&width=[width]&cacheKiller=[cacheKiller]&compId=[compId]&viewMode=[viewMode]&locale=[locale]&deviceType[device]
NameValueComments
endpointThe Widget URL as supplied during the app registration in the Dev Center
app-stateThe inner state of the page extensionThe app-state part of the URL may include a query string, but must not include a #
instanceThe signed instance
section-urlThe base URL of the page extension
targetAttribute that must be added to all href anchors within the page iframe
widthThe width of the iframe in pixelsNote that the frame height will auto-adjust depending on the frame content
cacheKillerThe cacheKiller is there to ensure no caching of the iframe content by the host browser
compIdThe ID of the extensionWhile the instanceId remain constant within the scope of the site, each iframe will have a unique and persistent compId
viewModeCurrent view mode"editor" or "site". "editor" is valid inside the Wix editor, while "site" is available only in a published website
localeCurrent locale value
deviceTypeCurrent device type"desktop" or "mobile"

App Settings request URL template

Copy
1
[endpoint]?instance=[signed-instance-data]&width=[width]&compId=tpaSettings&origCompId=[origCompId]&locale=[locale]
NameValueComments
endpointThe App Settings URL as supplied during the app registration in the Dev Center
instanceThe signed instance
widthThe width of the iframe in pixels
compIdThe compId value for the app settings is always tpaSettings
origCompIdThe ID of the extension which associated with the App SettingsThe origCompId identifies the current extension that the user is editing
localeCurrent locale value

Security and privacy

It's really important to make sure your app is secure and protects the user's privacy. We've got a dedicated guide to help you with this.

Was this helpful?
Yes
No