Self-host the API Management developer portal

This tutorial describes how to self-host the API Management developer portal. Self-hosting gives you flexibility to extend the developer portal with custom logic and widgets that dynamically customize pages on runtime. You can self-host multiple portals for your API Management instance, with different features. When you self-host a portal, you become its maintainer and you are responsible for its upgrades.

The following steps show how to set up your local development environment, carry out changes in the developer portal, and publish and deploy them to an Azure storage account.

If you have already uploaded or modified media files in the managed portal, see Move from managed to self-hosted, later in this article.

Availability

Important

This feature is available in the Premium, Standard, Basic, and Developer tiers of API Management.

Prerequisites

To set up a local development environment, you need to have:

Step 1: Set up local environment

To set up your local environment, you'll have to clone the repository, switch to the latest release of the developer portal, and install npm packages.

  1. Clone the api-management-developer-portal repo from GitHub:

    git clone https://github.com/Azure/api-management-developer-portal.git
    
  2. Go to your local copy of the repo:

    cd api-management-developer-portal
    
  3. Check out the latest release of the portal.

    Before you run the following code, check the current release tag in the Releases section of the repository and replace <current-release-tag> value with the latest release tag.

    git checkout <current-release-tag>
    
  4. Install any available npm packages:

    npm install
    

Tip

Always use the latest portal release and keep your forked portal up-to-date. The Software Engineers use the master branch of this repository for daily development purposes. It has unstable versions of the software.

Step 2: Configure JSON files, static website, and CORS settings

The developer portal requires the API Management REST API to manage the content.

config.design.json file

Go to the src folder and open the config.design.json file.

{
  "environment": "development",
  "managementApiUrl": "https://<service-name>.management.azure-api.net",
  "managementApiAccessToken": "SharedAccessSignature ...",
  "backendUrl": "https://<service-name>.developer.azure-api.net",
  "useHipCaptcha": false
}

Configure the file:

  1. In the managementApiUrl value, replace <service-name> with the name of your API Management instance. If you configured a custom domain, use it instead (for example, https://management.contoso.com).

    {
    ...
    "managementApiUrl": "https://contoso-api.management.azure-api.net"
    ...
    
  2. Manually create a SAS token to enable the direct REST API access to your API Management instance.

  3. Copy the generated token and paste it as the managementApiAccessToken value.

  4. In the backendUrl value, replace <service-name> with the name of your API Management instance. If you configured a custom domain, use it instead (for example, https://portal.contoso.com).

    {
    ...
    "backendUrl": "https://contoso-api.developer.azure-api.net"
    ...
    
  5. If you'd like to enable CAPTCHA in your developer portal, see Enable CAPTCHA.

config.publish.json file

Go to the src folder and open the config.publish.json file.

{
  "environment": "publishing",
  "managementApiUrl": "https://<service-name>.management.azure-api.net",
  "managementApiAccessToken": "SharedAccessSignature...",
  "useHipCaptcha": false
}

Configure the file:

  1. Copy and paste the managementApiUrl and managementApiAccessToken values from the previous configuration file.

  2. If you'd like to enable CAPTCHA in your developer portal, see Enable CAPTCHA.

config.runtime.json file

Go to the src folder and open the config.runtime.json file.

{
  "environment": "runtime",
  "managementApiUrl": "https://<service-name>.management.azure-api.net",
  "backendUrl": "https://<service-name>.developer.azure-api.net"
}

Configure the file:

  1. Copy and paste the managementApiUrl value from the previous configuration file.

  2. In the backendUrl value, replace <service-name> with the name of your API Management instance. If you configured a custom domain, use it instead (for example. https://portal.contoso.com).

    {
    ...
    "backendUrl": "https://contoso-api.developer.azure-api.net"
    ...
    

Configure the static website

Configure the Static website feature in your storage account by providing routes to the index and error pages:

  1. Go to your storage account in the Azure portal and select Static website from the menu on the left.

  2. On the Static website page, select Enabled.

  3. In the Index document name field, enter index.html.

  4. In the Error document path field, enter 404/index.html.

  5. Select Save.

Configure the CORS settings

Configure the Cross-Origin Resource Sharing (CORS) settings:

  1. Go to your storage account in the Azure portal and select CORS from the menu on the left.

  2. In the Blob service tab, configure the following rules:

    Rule Value
    Allowed origins *
    Allowed methods Select all the HTTP verbs.
    Allowed headers *
    Exposed headers *
    Max age 0
  3. Select Save.

Step 3: Run the portal

Now you can build and run a local portal instance in the development mode. In development mode, all the optimizations are turned off and the source maps are turned on.

Run the following command:

npm start

After a short time, the default browser automatically opens with your local developer portal instance. The default address is http://localhost:8080, but the port can change if 8080 is already occupied. Any changes to the codebase of the project will trigger a rebuild and refresh your browser window.

Step 4: Edit through the visual editor

Use the visual editor to carry out these tasks:

  • Customize your portal
  • Author content
  • Organize the structure of the website
  • Stylize its appearance

See Tutorial: Access and customize the developer portal. It covers the basics of the administrative user interface and lists recommended changes to the default content. Save all changes in the local environment, and press Ctrl+C to close it.

Step 5: Publish locally

The portal data originates in the form of strong-typed objects. The following command translates them into static files and places the output in the ./dist/website directory:

npm run publish

Step 6: Upload static files to a blob

Use Azure CLI to upload the locally generated static files to a blob, and make sure your visitors can get to them:

  1. Open Windows Command Prompt, PowerShell, or other command shell.

  2. Run the following Azure CLI command.

    Replace <account-connection-string> with the connection string of your storage account. You can get it from the Access keys section of your storage account.

    az storage blob upload-batch --source dist/website \
        --destination '$web' \
        --connection-string <account-connection-string>
    

Step 7: Go to your website

Your website is now live under the hostname specified in your Azure Storage properties (Primary endpoint in Static websites).

Step 8: Change API Management notification templates

Replace the developer portal URL in the API Management notification templates to point to your self-hosted portal. See How to configure notifications and email templates in Azure API Management.

In particular, carry out the following changes to the default templates:

Note

The values in the following Updated sections assume that you're hosting the portal at https://portal.contoso.com/.

Email change confirmation

Update the developer portal URL in the Email change confirmation notification template:

Original content

<a id="confirmUrl" href="$ConfirmUrl" style="text-decoration:none">
  <strong>$ConfirmUrl</strong></a>

Updated

<a id="confirmUrl" href="https://portal.contoso.com/signup?$ConfirmQuery" style="text-decoration:none">
  <strong>https://portal.contoso.com/signup?$ConfirmQuery</strong></a>

New developer account confirmation

Update the developer portal URL in the New developer account confirmation notification template:

Original content

<a id="confirmUrl" href="$ConfirmUrl" style="text-decoration:none">
  <strong>$ConfirmUrl</strong></a>

Updated

<a id="confirmUrl" href="https://portal.contoso.com/signup?$ConfirmQuery" style="text-decoration:none">
  <strong>https://portal.contoso.com/signup?$ConfirmQuery</strong></a>

Invite user

Update the developer portal URL in the Invite user notification template:

Original content

<a href="$ConfirmUrl">$ConfirmUrl</a>

Updated

<a href="https://portal.contoso.com/confirm-v2/identities/basic/invite?$ConfirmQuery">https://portal.contoso.com/confirm-v2/identities/basic/invite?$ConfirmQuery</a>

New subscription activated

Update the developer portal URL in the New subscription activated notification template:

Original content

Thank you for subscribing to the <a href="http://$DevPortalUrl/products/$ProdId"><strong>$ProdName</strong></a> and welcome to the $OrganizationName developer community. We are delighted to have you as part of the team and are looking forward to the amazing applications you will build using our API!

Updated

Thank you for subscribing to the <a href="https://portal.contoso.com/product#product=$ProdId"><strong>$ProdName</strong></a> and welcome to the $OrganizationName developer community. We are delighted to have you as part of the team and are looking forward to the amazing applications you will build using our API!

Original content

Visit the developer <a href="http://$DevPortalUrl/developer">profile area</a> to manage your subscription and subscription keys

Updated

Visit the developer <a href="https://portal.contoso.com/profile">profile area</a> to manage your subscription and subscription keys

Original content

<a href="http://$DevPortalUrl/docs/services?product=$ProdId">Learn about the API</a>

Updated

<a href="https://portal.contoso.com/product#product=$ProdId">Learn about the API</a>

Original content

<p style="font-size:12pt;font-family:'Segoe UI'">
  <strong>
    <a href="http://$DevPortalUrl/applications">Feature your app in the app gallery</a>
  </strong>
</p>
<p style="font-size:12pt;font-family:'Segoe UI'">You can publish your application on our gallery for increased visibility to potential new users.</p>
<p style="font-size:12pt;font-family:'Segoe UI'">
  <strong>
    <a href="http://$DevPortalUrl/issues">Stay in touch</a>
  </strong>
</p>
<p style="font-size:12pt;font-family:'Segoe UI'">
      If you have an issue, a question, a suggestion, a request, or if you just want to tell us something, go to the <a href="http://$DevPortalUrl/issues">Issues</a> page on the developer portal and create a new topic.
</p>

Updated

<!--Remove the entire block of HTML code above.-->

Password change confirmation

Update the developer portal URL in the Password change confirmation notification template:

Original content

<a href="$DevPortalUrl">$DevPortalUrl</a>

Updated

<a href="https://portal.contoso.com/confirm-password?$ConfirmQuery">https://portal.contoso.com/confirm-password?$ConfirmQuery</a>

All templates

Update the developer portal URL in any template that has a link in the footer:

Original content

<a href="$DevPortalUrl">$DevPortalUrl</a>

Updated

<a href="https://portal.contoso.com/">https://portal.contoso.com/</a>

Move from managed to self-hosted developer portal

Over time, your business requirements may change. You can end up in a situation where the managed version of the API Management developer portal no longer satisfies your needs. For example, a new requirement may force you to build a custom widget that integrates with a third-party data provider. Unlike the manged version, the self-hosted version of the portal offers you full flexibility and extensibility.

Transition process

You can transition from the managed version to a self-hosted version within the same API Management service instance. The process preserves the modifications that you've carried out in the managed version of the portal. Make sure you back up the portal's content beforehand. You can find the backup script in the scripts folder of the API Management developer portal GitHub repo.

The conversion process is almost identical to setting up a generic self-hosted portal, as shown in previous steps in this article. There is one exception in the configuration step. The storage account in the config.design.json file needs to be the same as the storage account of the managed version of the portal. See Tutorial: Use a Linux VM system-assigned identity to access Azure Storage via a SAS credential for instructions on how to retrieve the SAS URL.

Tip

We recommend using a separate storage account in the config.publish.json file. This approach gives you more control and simplifies the management of the hosting service of your portal.

Enable CAPTCHA

When setting up the self-hosted portal, you may have disabled CAPTCHA through the useHipCaptcha setting. Communication with CAPTCHA happens through an endpoint, which lets Cross-Origin Resource Sharing (CORS) happen for only the managed developer portal hostname. If your developer portal is self-hosted, it uses a different hostname and CAPTCHA won't allow the communication.

Update the JSON config files

To enable the CAPTCHA in your self-hosted portal:

  1. Assign a custom domain (for example, api.contoso.com) to the Developer portal endpoint of your API Management service.

    This domain applies to the managed version of your portal and the CAPTCHA endpoint. For steps, see Configure a custom domain name for your Azure API Management instance.

  2. Go to the src folder in the local environment for your self-hosted portal.

  3. Update the configuration json files:

    File New value Note
    config.design.json "backendUrl": "https://<custom-domain>" Replace <custom-domain> with the custom domain you set up in the first step.
    "useHipCaptcha": true Change the value to true
    config.publish.json "backendUrl": "https://<custom-domain>" Replace <custom-domain> with the custom domain you set up in the first step.
    "useHipCaptcha": true Change the value to true
    config.runtime.json "backendUrl": "https://<custom-domain>" Replace <custom-domain> with the custom domain you set up in the first step.
  4. Publish the portal.

  5. Upload and host the newly published portal.

  6. Expose the self-hosted portal through a custom domain.

The portal domain's first and second levels need to match the domain set up in the first step. For example, portal.contoso.com. The exact steps depend on your hosting platform of choice. If you used an Azure storage account, you can refer to Map a custom domain to an Azure Blob Storage endpoint for instructions.

Next steps