How to create a setup table and page for your app

Great customizations need a great setup experience. Check out this video for an approach to adding a proper setup area to your app:

https://youtu.be/YwNTmTwzWuw

In this video, Erik walks through the complete process of creating a dedicated setup table and page for your Business Central app using AL. He explains why you should avoid extending existing setup tables (like Sales & Receivables Setup or General Ledger Setup), demonstrates the “single-record table” pattern, shows how to make the page user-friendly, and finishes by registering the setup in the Assisted Setup guide so users are prompted to configure your app right after installation.

Why You Need Your Own Setup Table

A common approach — especially from the older days of Business Central / NAV development — is to extend an existing setup table such as Sales & Receivables Setup or General Ledger Setup. You add your fields there, put them on the page, and you’re done. While this is quick, Erik explains why it’s a bad practice:

  • Security: There’s no way to control security for your app’s setup independently from the base setup table you’re extending.
  • Scalability: Your app might start with one field, but soon grows to two, four, or eight fields — cluttering someone else’s setup page.
  • Isolation: Having your own setup table and page keeps your app’s configuration cleanly separated.

Creating the Setup Table

The setup table follows a well-known pattern in Business Central: it’s a single-record table. The trick to ensuring only one record ever exists is to have a primary key field that nobody ever gets to populate. Since Business Central requires every table to have a primary key, you create a Code[10] field called “Primary Key” — following Microsoft’s own convention — but you never expose it on the UI.

table 50600 "MyApp Setup"
{
    Caption = 'MyApp Setup';
    DataClassification = ToBeClassified;
    
    fields
    {
        field(1; "Primary Key"; Code[10])
        {
            Caption = 'Primary Key';
            DataClassification = ToBeClassified;
        }
        field(10; "Important Setup 1"; Date)
        {
            Caption = 'Important Setup 1';
            DataClassification = ToBeClassified;
        }
        field(11; "Important Account"; Code[20])
        {
            Caption = 'Important Account';
            DataClassification = ToBeClassified;
        }
        field(12; "Important Item"; Code[20])
        {
            Caption = 'Important Item';
            DataClassification = ToBeClassified;
        }
    }
    keys
    {
        key(PK; "Primary Key")
        {
            Clustered = true;
        }
    }
}

Because the “Primary Key” field is never shown to the user and defaults to an empty value, no one can ever insert a second record — the primary key would always be blank, and you can’t have two records with the same primary key. This guarantees a single-record table.

Creating the Setup Page

The setup page is a Card page type that sources from the setup table. There are several important design decisions that make this page behave correctly:

Don’t Expose the Primary Key

The primary key field is deliberately left off the page layout. If users can’t see or edit it, they can’t create additional records.

Auto-Insert the Record

When a user first opens the setup page, there’s no record yet — which means the page would appear empty and non-editable. To solve this, Erik adds an OnInit trigger that automatically inserts a blank record if the table is empty:

trigger OnInit()
begin
    if Rec.IsEmpty() then
        Rec.Insert();
end;

This way, the moment a user opens the setup page for the first time, the record is created and they can immediately start editing.

Disable Insert and Delete

To prevent users from creating additional records (via the “+” button) or accidentally deleting the setup, both operations are disabled on the page:

InsertAllowed = false;
DeleteAllowed = false;

Make It Searchable

Adding UsageCategory and ApplicationArea ensures the page appears in the search results when users type the page name in the Tell Me search bar. This also affects how the page opens — when launched from search, it opens directly in edit mode, which is exactly what you want for a setup page.

Here’s the complete setup page:

page 50600 "MyApp Setup"
{
    Caption = 'MyApp Setup';
    PageType = Card;
    SourceTable = "MyApp Setup";
    InsertAllowed = false;
    DeleteAllowed = false;
    UsageCategory = Administration;
    ApplicationArea = all;

    layout
    {
        area(Content)
        {
            group(General)
            {
                Caption = 'General Setup';
                field("Important Setup 1"; Rec."Important Setup 1")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the value of the Important Setup 1 field.';
                }
                field("Important Account"; Rec."Important Account")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the value of the Important Account field.';
                }
                field("Important Item"; Rec."Important Item")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the value of the Important Item field.';
                }
            }
        }
    }
    trigger OnInit()
    begin
        if Rec.IsEmpty() then
            Rec.Insert();
    end;
}

Registering in Assisted Setup

This is where things get really polished. Business Central has an Assisted Setup page that lists guided setups for various features and apps. By registering your setup page there, you get two significant benefits:

  • Your setup appears alongside all other setup wizards in the Assisted Setup list.
  • Starting with version 21, if your app has a registered assisted setup entry, Business Central will automatically open the setup page after your app is installed. Users also get a “Setup” action when viewing your app in Extension Management.

To register, you subscribe to the OnRegisterAssistedSetup event on the Guided Experience codeunit and call InsertAssistedSetup:

codeunit 50600 "MyApp Mgt"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Guided Experience", 'OnRegisterAssistedSetup', '', true, true)]
    local procedure MyAppSetupRegister()
    var
        GuideExperience: Codeunit "Guided Experience";
    begin
        GuideExperience.InsertAssistedSetup(
            'MyApp Setup',
            'The best app',
            'An even better app',
            2,
            ObjectType::Page,
            Page::"MyApp Setup",
            Enum::"Assisted Setup Group"::Analysis,
            'https://youtube.com/hougaard',
            Enum::"Video Category"::Analysis,
            'https://www.hougaard.com'
        );
    end;
}

The InsertAssistedSetup function takes quite a few parameters:

  1. Title — The name shown in the assisted setup list
  2. Short Title — A shorter version (max 50 characters)
  3. Description — A longer description of what the setup does
  4. Expected Duration — How many minutes the setup is expected to take
  5. Object Type — The type of object to run (typically ObjectType::Page)
  6. Object ID — The specific page to open
  7. Assisted Setup Group — Which category to file it under
  8. Video URL — A link to a help video
  9. Video Category — The category for the video
  10. Help URL — A link to documentation

Watch Out for the Short Title Length

Erik shares a hard-earned lesson here: the short title field is limited to 50 characters. This compiles fine and passes AppSource validation even if a translated label exceeds 50 characters. However, when a user running that language tries to install the app, it will break at runtime — a frustrating issue to debug. Erik’s workaround was to wrap the label value in a CopyStr call to ensure it never exceeds the limit, regardless of translation length.

Summary

Creating a proper setup table and page for your Business Central app involves three components working together:

  • A single-record table with an unexposed Code[10] primary key field
  • A Card page that auto-inserts the record on first open, disables insert/delete, and is searchable via Tell Me
  • An Assisted Setup registration that integrates your setup into the standard Business Central setup experience and enables automatic setup prompts after app installation

This pattern gives you clean separation of concerns, proper security control, a polished user experience, and seamless integration with the Business Central platform — well worth the small amount of extra effort compared to tacking fields onto an existing setup table.