# Returns Portal v2 Snippet

This page focuses on the **embedded** Returns Portal (web component snippet). If you want to use the **hosted** Returns App (no embed), jump to [Hosted Returns App (no embed)](#hosted-returns-app-no-embed).

{% hint style="info" %}
This article describes the configuration for Returns Portal **v2.**
{% endhint %}

## Setting Up the Returns Portal Snippet

The following instructions explain the basics of setting up the Returns Portal snippet and how you can customize the data settings in two easy steps, followed by optional advanced configuration for your Returns Portal.

{% stepper %}
{% step %}

#### Add the snippet to your website

To insert the snippet onto a page on your website or online shop:

1. Create an empty landing page, for example: at `/returns-portal`.
2. Copy the following snippet and paste it somewhere in the `<body />` (*not* the `<head />`) of your page where you want the Returns Portal to be displayed.

{% hint style="info" %}
The best place for the snippet would be a responsive content container of your page where the main content is usually displayed.
{% endhint %}

This will automatically load our JS snippet and default CSS. The plugin will be rendered in the defined DOM node.

{% code overflow="wrap" %}

```html
<pl-returns-portal
  code="your-portal-code"
  account-name="parcellab-account-name"
>
</pl-returns-portal>

<script
  type="module"
  src="https://returns-app.parcellab.com/static/plugin/js/loader.mjs"
>
</script>
```

{% endcode %}

{% hint style="info" %}
The plugin features automatic environment detection, so you can use the same snippet in your staging and production environments.
{% endhint %}
{% endstep %}

{% step %}

#### Modify the data settings

The data settings of the Returns Portal widget will have to be updated based on the following attributes:

<table><thead><tr><th width="148.3359375">Data Attribute</th><th width="104.1484375">Necessity</th><th width="277.1328125">Description</th><th>Example</th></tr></thead><tbody><tr><td>code</td><td>Required</td><td>Your unique Returns Portal code.</td><td>xt-de</td></tr><tr><td>account-name</td><td>Required</td><td>Your parcelLab user ID or technical account name.</td><td><ul><li>16147742</li><li>weareparkers</li></ul></td></tr><tr><td>entry-point</td><td>Optional</td><td>The starting page for the Returns Portal.<br>Default value is <code>returns</code>, where users start at the order search page.<br>For <a href="#id-2-orderless-registration-entry">orderless returns</a>, set the value to <code>registration</code>.</td><td>registration</td></tr><tr><td>environment</td><td>Optional</td><td>This allows you to override the automatic environment detection.<br><br>Default value is <code>live</code>, and uses the production server.</td><td><ul><li>development</li><li>staging</li><li>live</li></ul></td></tr><tr><td>lang</td><td>Optional</td><td><p>The ISO-2 language code for the initial language to load.</p><p>The widget will be displayed in the specified language.<br>This attribute can also be set via URL query parameter (for example: <code>?lang=de</code>)</p></td><td>de</td></tr></tbody></table>

Here is an example of the snippet with modified data settings:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Returns Portal</title>
  </head>
  <body>
    <header>
      <h1>Our Returns Portal</h1>
    </header>

    <main>
      <div class="container">
        <pl-returns-portal code="xt-de" account-name="parkersdemo">
        </pl-returns-portal>
      </div>
    </main>

    <footer>
      <p>&copy; 2025 Powered by parcelLab</p>
    </footer>

    <script
      type="module"
      src="https://returns-app.parcellab.com/static/plugin/js/loader.mjs"
    ></script>
  </body>
</html>

```

{% endstep %}

{% step %}

#### Advanced configuration

<details>

<summary>Styling</summary>

The web component creates a shadow DOM to isolate styles and takes 100% width of its container.

To control the portal size, you can style the container element.

<pre class="language-css"><code class="lang-css"><strong>.returns-container {
</strong>  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}
</code></pre>

The element automatically adjusts its height to fit the content.

</details>

<details>

<summary>Environment Detection</summary>

The plugin automatically detects the environment based on the host URL (that is: your website):

* `localhost` → Development
* `.parcellab.dev` or `staging*` → Staging
* All other domains → Live/Production

You can also force a specific server via URL query parameter, like in the following example:

```
https://yoursite.com/returns?server=https://returns-app.staging.parcellab.dev
```

</details>

<details>

<summary>Draft Mode</summary>

To preview your draft Returns Portal configuration, append the query parameter `draft=true` to the end of the URL for your Returns Portal.

You can combine with language and server overrides, like in the following example:

<pre class="language-html"><code class="lang-html"><strong>https://yoursite.com/returns?draft=true&#x26;lang=de&#x26;server=https://returns-app.staging.parcellab.dev
</strong></code></pre>

</details>

<details>

<summary>URL Hash Navigation</summary>

The Returns Portal v2 plugin supports hash-based navigation. Users can bookmark or share specific pages, like in the following examples:

* [https://yoursite.com/returns#/registration/](https://yoursite.com/returns#/registration/https://yoursite.com/returns#/12345/address/https://yoursite.com/returns#/12345/articles/)
* [https://yoursite.com/returns#/12345/address/](https://yoursite.com/returns#/registration/https://yoursite.com/returns#/12345/address/https://yoursite.com/returns#/12345/articles/)
* [https://yoursite.com/returns#/12345/articles/](https://yoursite.com/returns#/registration/https://yoursite.com/returns#/12345/address/https://yoursite.com/returns#/12345/articles/)

</details>

<details>

<summary>Browser Support</summary>

The v2 plugin uses Web Components (Custom Elements) and requires modern browser support:

* Chrome/Edge 54+
* Firefox 63+
* Safari 10.1+

When using the ES module loader (`loader.mjs`), ensure browsers support ES modules. For legacy browsers, add the [no-module fallback](https://docs.parcellab.com/docs/developers/returns/configuration/v2#legacy-no-module-fallback).

</details>

<details>

<summary>Legacy/No-module Fallback</summary>

If you need to support browsers without ES module support, add a no-module fallback.

Modern browsers will load the module, and legacy browsers will load the fallback.

The following example shows the plugin script with an additional no-module fallback script.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;script
</strong>  type="module"
  src="https://returns-app.parcellab.com/static/plugin/js/loader.mjs"
>&#x3C;/script>
&#x3C;script
  nomodule
  src="https://returns-app.parcellab.com/static/plugin/js/loader.latest.js"
  async
  defer
>&#x3C;/script>
</code></pre>

</details>

<details>

<summary>Content Security Policy (CSP)</summary>

If your site uses CSP headers, you need to allow the parcelLab returns domain in your policy:

```html
frame-src 'self' https://returns-app.parcellab.com https://returns-app.staging.parcellab.dev;
```

For development environments, please include the following:

```
frame-src 'self' https://returns-app.parcellab.com https://returns-app.staging.parcellab.dev http://localhost:8000;
```

**Required directives**

* `frame-src`: Must include the returns portal domain(s)
* `script-src`: Must include the domain serving the loader script

**Example CSP header including the parcelLab Returns domain**

```html
Content-Security-Policy:
  default-src 'self';
  frame-src 'self' https://returns-app.parcellab.com https://returns-app.staging.parcellab.dev;
  script-src 'self' https://returns-app.parcellab.com;
```

</details>
{% endstep %}
{% endstepper %}

## Troubleshooting

This section describes known errors and ways to troubleshoot common issues.

<details>

<summary>Returns Portal not loading</summary>

To troubleshoot this error:

1. Check browser console for errors
2. Verify `code` and `account-name` attributes are correct
3. Ensure the script tag is placed after the web component

</details>

<details>

<summary>Height issues</summary>

The plugin automatically adjusts height. If you see scrollbars, you can try the following:

* Ensure the container does not have a fixed height
* Check for CSS conflicts with the iframe

</details>

<details>

<summary>Navigation issues</summary>

The plugin uses hash-based routing.

To troubleshoot:

* Ensure your page does not conflict with hash changes
* Check that JavaScript is enabled

</details>

## Hosted Returns App (no embed)

Use this when you want to send customers to parcelLab’s hosted returns experience. You do not add the `<pl-returns-portal>` snippet to your site, instead parcelLab will host your returns portal. You can access the hosted page directly from your **Returns configuration** in app.parcellab.com.

#### 1) Standard returns login via order search (default)

By default, customers login with their order reference and their email address or shipping postal code.

* Native route of this portal when hosted: `/<account>/<portal-code>/`
* Embedded equivalent `<pl-returns-portal code="<portal-code>" account-name="<account>"></pl-returns-portal>`

To log a customer automatically in from e.g. their account section to the returns portal to initiate a return for a hosted or embedded portal, add `reference` (order number) and `identifier` (email or postal code) as query search parameters to the URL.

**Example:** `...?reference=ORD-123&identifier=user@example.com`

#### 2) Orderless registration entry

For orderless returns, customers do not have to provide an order number. Instead, they register their items to be returned manually or by searching the product catalog. This option needs to be activated in the returns portal options and a manual review of registered returns is recommended.

* Native route of this portal when hosted: `/<account>/<portal-code>/registration/`
* Embedded equivalent: `<pl-returns-portal code="<portal-code>" account-name="<account>" entry-point="registration"></pl-returns-portal>`

#### 3) Receive UI entry (warehouse)

Use this UI to **process returns in the warehouse** if you do not have a WMS flow. Receiving a return in UI accepts the quantity and settles the return by issuing refunds and releasing exchanges where appropriate.

{% hint style="info" %}
The Receive UI requires the user to be logged in to parcelLab.
{% endhint %}

* Native route of this portal when hosted: `/<account>/<portal-code>/receive/`
* Note on embedding: The Receive UI is not designed to be embedded.

### Deep linking to the returns portal (auto-login)

To send a customer straight into the returns flow, construct a URL like this:

1. Start with your hosted or embedded base URL.
2. Point it at the entry route (`/` or `/registration/`).
3. Add `/#/` before the query parameters
4. Append the query params (`reference`, `identifier`, ...).

If you embed the portal on your own site, your URL typically looks like:

`https://<your-domain>/<your-returns-page>/#/<account>/<portal-code>/?reference=<ref>&identifier=<id>`

## Supported Languages

The Returns Portal is available with default translations in the following languages. Dates and timestamps are automatically formatted according to the configured country and language for your Returns Portal.

<details>

<summary>List of supported languages</summary>

* Albanian
* Bosnian
* Bulgarian
* Chinese (simplified)
* Croatian
* Czech
* Danish
* Dutch
* English (UK)
* English (US)
* Estonian
* Finnish
* French
* German
* German (formal)
* Greek
* Hungarian
* Italian
* Japanese
* Korean
* Latvian
* Lithuanian
* Norwegian
* Polish
* Portuguese
* Romanian (formal)
* Serbian (Latin)
* Slovak
* Slovenian
* Spanish
* Swedish
* Turkish

</details>

{% hint style="info" %}
To modify any of the default translations used in your Returns Portal, please contact your parcelLab representative.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.parcellab.com/docs/developers/returns/v2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
