Polaris uses Django’s template system for defining the UI content rendered to users, and these templates can be written in a way that allows others to override or extend them. Specifically, Polaris’ templates have the following inheritance structure:

  • templates/polaris/base.html
    • templates/polaris/deposit.html
    • templates/polaris/withdraw.html
    • templates/polaris/more_info.html

base.html defines the top-level HTML tags like html, body, and head, while each of the four other templates extend the file and override the content block, among others. deposit.html and withdraw.html are very similar and are used for pages that display forms. more_info.html simply displays transaction details.

Template Extensions

In order to override or extend a Polaris Template, anchors must create a file with the same path and name of the file its replacing. Once created, the anchor can override any block tag defined in the template (or it’s parent templates).

Polaris provides two block tags that are intentionally left empty for anchors to extend: extra_head and extra_body. You are also allowed to extend any of the blocks actually implemented by Polaris, such as header, content, and footer. Note that header contains extra_header.

For example, the SDF’s reference server extends base.html by creating an HTML file within the app’s templates/polaris directory. In the file, we declare the template we are extending, load any django-provided templates tools such as static, and define an extra_body block:

{% extends "polaris/base.html" %} {% load static %} {% load i18n %}

{% trans "Confirm Email" as ce %}

{% block extra_body %}

    <script src="https://www.googletagmanager.com/gtag/js?id=UA-53373928-6" async></script>
    <script src="{% static 'sep24_scripts/google_analytics.js' %}"></script>

    {% if not form is not None and title != ce %}
        <script src="{% static 'sep24_scripts/check_email_confirmation.js' %}"></script>
    {% endif %}

{% endblock %}

The extra_body block adds <script> tags for a Google Analytics and a local script within the app’s static directory that requests the email confirmation status of the user on page focus, improving UX. If you’re unfamiliar with the syntax of Django’s templates, check out the template syntax documentation and particularly the block documentation. The extra_head template block is ideal for linking anchor-defined CSS files or other resources that must load before the page is displayed.

Note that the content rendered within extra_body and extra_head is in addition to the content defined by Polaris’ templates. If you wish to replace a template completely, create a file with the same relative path from the templates directory but do not use the extend keyword. Instead, simply write a Django template that does not extend one defined by Polaris.

Template Contexts

Whenever a template is rendered and displayed to the user, its rendered using a context, which is a Python dictionary containing key-value pairs that can be used to alter the content rendered. Polaris has an integration function that allows anchors to add key-value pairs to the context used whenever a template is about to be rendered.

polaris.integrations.DepositIntegration.content_for_template(self, template: polaris.templates.Template, form: Optional[django.forms.forms.Form] = None, transaction: Optional[polaris.models.Transaction] = None) → Optional[Dict[KT, VT]]

Return a dictionary containing page content to be used in the template passed for the given form and transaction.

Polaris will pass one of the following polaris.templates.Template values:


The template used for deposit flows


The template used to show transaction details

The form parameter will always be None when template is Template.MORE_INFO since that page does not display form content.

If form is None and template_name is not Template.MORE_INFO, returning None will signal to Polaris that the anchor is done collecting information for the transaction. Returning content will signal to Polaris that the user needs to take some action before receiving the next form, such as confirming their email. In this case, make sure to return an appropriate guidance message.

Using this function, anchors pass key-value pairs to the template being rendered. Some of these key-value pairs are used by Polaris, but anchors are allowed and encouraged to extend Polaris’ templates and pass custom key-value pairs.

def content_for_template(template_name, form=None, transaction=None):
    return {
        "title": "Deposit Transaction Form",
        "guidance": "Please enter the amount you would like to deposit.",
        "icon_label": "Stellar Development Foundation",
        "icon_path": "images/company-icon.png",
        # custom field passed by the anchor
        "username": "John.Doe"

title is the browser tab’s title, and guidance is shown as plain text on the page. icon_label is the label for the icon specified by icon_path.

icon_path should be the relative file path to the image you would like to use as the company icon in the UI. The file path should be relative to the value of your STATIC_ROOT setting. If icon_path is not present, Polaris will use the image specified by your TOML integration function’s ORG_LOGO key.

Finally, if neither are present, Polaris will default to its default image. All images will be rendered in a 100 x 150px sized box.

  • template – a polaris.templates.Template enum value for the template to be rendered in the response
  • form – the form to be rendered in the template
  • transaction – the transaction being processed
polaris.integrations.WithdrawalIntegration.content_for_template(self, template: polaris.templates.Template, form: Optional[django.forms.forms.Form] = None, transaction: Optional[polaris.models.Transaction] = None)

Same as DepositIntegration.content_for_template, except the Template values passed will be one of:


The template used for withdraw flows


The template used to show transaction details
  • template – a polaris.templates.Template enum value for the template to be rendered in the response
  • form – the form to be rendered in the template
  • transaction – the transaction being processed

Using this function in conjunction with template extensions, you can define template blocks that use context variables passed from content_for_template(). This gives anchors complete control of the interactive UX.

Outlined below are the default key-value pairs passed as context objects to each template. In addition to the attributes listed in each Template section, Polaris also passes the key-value pairs returned from content_for_template().


  • form: The Django Form object return by form_for_transaction()
  • post_url: The URL to use when making the POST request containing form data
  • get_url: The URL to use when making the GET request for the form
  • scripts: A list of TemplateScript objects (deprecated)
  • operation: The /fee?operation= value for the transaction
  • asset: The Polaris Asset object for the transaction requested
  • use_fee_endpoint: A boolean for whether the anchor requires the custom fee endpoint
  • org_logo_url: A URL to the organization’s logo, to be used as the page center icon


All attributes listed here have identical definitions to the above set of attributes:

  • form
  • post_url
  • get_url
  • scripts
  • operation
  • asset
  • use_fee_endpoint


  • tx_json: A JSON-serialized object matching the response body from /transactions
  • amount_in: The amount sent to the anchor’s account
  • amount_out: The amount send to the user’s account
  • amount_fee: The amount charged by the anchor for facilitating the transaction
  • transaction: The Transaction Polaris database object
  • asset_code: The code string representing the asset