UniFi - Hotspot Portal Customization


Readers will learn how to customize the built-in UniFi hotspot portal.

info_i_25x25.png Note: This article describes customization of the legacy hotspot portal. The current AngularJS portal is explained in the UniFi Guest Portal Customization & Hotspot System and the UniFi - Wireless Guest Network Setup articles.

Unlike other guest portal implementations that have disk space limitations, fixed directory structures, and all sorts of restrictions, UniFi allows for almost unlimited portal customization using plain html.

The entire portal directory is open for your modifications. You can instantly test as you go by saving the file and reloading the page from the guest's browser to review changes.

Moreover, you can create multiple hotspot packages - each with different payment, name, duration of use, bandwidth limit.

This article will give an overview of some of the most common variables.


  1. In Settings->Guest Control, enable Guest Portal and Portal Customization.
  2. Hit 'Apply.' A copy of the portal pages will be copied to <unifi_base>/data/portal (v2.x) or <unifi_base>/data/sites/sitename/portal (v3.x)
  3. Use another PC to connect to the guest network and and use the browser to navigate to any website.
  4. You will be directed to the default portal page.
  5. Modify the page(s) (e.g. the <title>) and view your changes by reloading the browser on the client.
info_i_25x25.png Note: The location <unifi_base> will vary depending on your operating system. See this article for more information.

Sample Portal
The sample portal, while useful by itself, is written in a way that it demonstrates most features in the simplest format.

# directory structure
index.html    : the main landing page
bundle/messages.properties: for localization and hotspot package specification
payment.html  : for credit card information submission. requires https, also served as an example of additional .html page
fail.html     : default page when there's error handling guest login

supporting files: 


  1. All .html pages go through the rendering engine and can be a target of the form's POST action.
  2. None of the supporting files are required and you can roll your own.
  3. After modifying the portal, you can see the modifications by pointing your browser at https://[IP of the controller]:8843/guest/s/default/.

To explain further, let's go through some scenarios. 


Can I just modify something and see if it works? Yes!

  1. On controller: enable Guest Portal, select No Authentication
  2. Modify index.html: find
    "<h2>Terms of Use</h2>"
    and change it to
    "<h2>Welcome to Joe's Guest Portal!</h2>"
  3. Use another device connected to the guest wireless network and open the browser to any URL to see changes.

How do I show a Terms of Use page with the customized portal?

On controller: Enable Guest Portal and Select No Authentication.

  1. Review the bottom portion of index.html. Adjust the ToU as you see fit.
  2. All that's required is that the form POST to /guest/login to authorize the user access to the guest network.
  3. The sample page requires the user to accept Terms of Use by disabling the submit button if they don't check the "I accept the Terms of Use."

How do I enable simple password authentication?

On controller: Enable Guest Portal, Select Simple Password.

  1. Find the section enclosed by <unifi if="auth_password"> ... </unifi>
  2. Requires the form POST ("password")
  3. The hidden "page_error" indicates which page will render the error, in the sample, index.html
  4. That leads us to look at the section of <unifi if="has_error"> where either the localized error <unifi error="error" /> or a welcome title <unifi txt="PasswordRequiredForWirelessAccess" /> will be displayed.

How do I integrate UniFi controller with Paypal Pro or Standard accounts?

We have compiled step-by-step examples that demonstrate how UniFi hotspot can be integrated with PayPal and PayPal Pro accounts. UniFi and PayPal Integration


Voucher Customization

Currently the voucher customization is not implemented yet. However, you can try to modify webapps/ROOT/pages/voucher.jsp

Note: Make sure that this file is backed up somewhere as it will be wiped out during controller upgrade/reinstall.

The JSP code is HTML-like and modifiable. The current implementation prints 4 vouchers per row with minimum formatting.

    <p class="valid">Valid for <%=valid%></p>
    <p class="code"><%=code%></p>

Another approach is to use API to create vouchers, and naturally you'll get the details of the voucher in JSON for custom formatting/printing (e.g. sending it to a receipt printer). 

Portal page syntax and variables

Some UniFi tags are listed below.

A few vars are populated where you can use <unifi var="varnames" /> to render it in the HTML page:

<unifi var="name" />
  • auth: none | password | hotspot
  • auth_none: false | true
  • auth_password: false | true
  • auth_hotspot: false | true
  • voucher_enabled: false | true
  • payment_enabled: false | true
  • package: the package id (from POST or GET)
  • mac: guest's MAC address
  • ap_mac: AP's MAC address
  • ap_name: AP's name
  • map_name: AP's location (name of the map)
  • ssid: the SSID of the wireless network
  • error: error message
  • has_error: false | true

To include another HTML page, use:

<unifi include="header.html" />

To use the simple if/then/else logic to determine if a section of the page should be shown use <unifi if="!name" eq="value" > ... </unifi>

<unifi include="header.html" /><unifi if="name" eq="value"> ... <unifi else="var" /> ... </unifi>

For text localization or to see bundle/messages.properties, use:

<unifi txt="InvalidPassword" />

To generate the URL (and possibly change it to HTTPs) relatively, use:

<unifi url="payment.html" https="true" />

Guest parameters

Operators can define parameters under the URL "/guest/login" where users will POST to be authorized:

  • by: type of authentication (for hotspot): voucher | credit | paypal
  • package: package id (for hotspot)
  • voucher: voucher code (for hotspot/voucher)
  • cc_xxxxx: credit card information (for hotspot/credit):
  • landing_url: use a dynamic landing URL (which can be constructed by using vars)
  • page_error: relative URI when error occurs (fail.html is the default)

Note: credit card related fields include cc_firstname, cc_lastname, cc_number, cc_year, cc_month, cc_ccv2 cc_addr1, cc_addr2, cc_city, cc_state, cc_zip, cc_country, cc_email

Package definitions

Users can define package definitions under the directory:

"bundle/messages.properties:package definitions"

## package 1
# amount is in US dollars
# default currency is USD
# what's shown in the Hotspot Manager
package.1.name=Basic 8HR
# what's shown on the credit card statement
package.1.charged_as=Hotspot 8-hour WiFi

## package 2
package.2.name=Premium Daypass
package.2.charged_as=Hotspot 1-day WiFi

## package 3
# this is a free trial package (with amount 0)
package.3.name=Free Trial
# whether to overwrite the user group policy per WLAN/User, default is false
# only available in release-2.1.0
# kbps, default is unlimited
# kbps, default is unlimited
# Mbytes, default is unlimited
Powered by Zendesk