> For the complete documentation index, see [llms.txt](https://docs.klai.studio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.klai.studio/getting-started/ide-quick-tour/4.-common-customizations-and-expanding-your-app/4.2-implementing-page-navigation-actions-and-site-navigation-ui.md).

# 4.2 Implementing Page Navigation (Actions & Site Navigation UI)

Navigation is a crucial aspect of any BetterForms application. This section covers both programmatic navigation using actions and setting up site-wide navigation menus that users can interact with.

## Two Types of Navigation in BetterForms

### 1. **Action-Based Navigation**

Navigation triggered by user actions (button clicks, form submissions, etc.)

### 2. **Site Navigation Menu**

Persistent navigation menus that appear on all pages (typically in the sidebar)

## Action-Based Navigation

### Using the `path` Action

The `path` action is the primary way to navigate between pages programmatically:

```json
{
  "action": "path",
  "options": {
    "path": "/dashboard"
  }
}
```

This action can be used in:

* **Button actions**
* **Form submissions**
* **Hook responses**
* **Navigation menu items**

### Navigation Button Examples

#### Basic Page Navigation

```json
{
  "type": "button",
  "text": "Go to Dashboard",
  "buttonClasses": "btn btn-primary",
  "styleClasses": "col-md-4",
  "actions": [{
    "action": "path",
    "options": {
      "path": "/dashboard"
    }
  }]
}
```

#### Navigation with Data

Pass data to the destination page using query parameters:

```json
{
  "type": "button",
  "text": "Edit Contact",
  "buttonClasses": "btn btn-info",
  "styleClasses": "col-md-4",
  "actions": [{
    "action": "path",
    "options": {
      "path": "/contact-edit?id=123&mode=edit"
    }
  }]
}
```

#### External Navigation

Link to external websites:

```json
{
  "type": "button",
  "text": "Open Documentation",
  "buttonClasses": "btn btn-secondary",
  "styleClasses": "col-md-4",
  "actions": [{
    "action": "path",
    "options": {
      "url": "https://docs.fmbetterforms.com/"
    }
  }]
}
```

### Save and Navigate Pattern

Common FileMaker developer pattern - save data then navigate:

```json
{
  "type": "button",
  "text": "Save & Return",
  "buttonClasses": "btn btn-success",
  "styleClasses": "col-md-4",
  "actions": [
    {
      "action": "runUtilityHook",
      "options": {
        "type": "save"
      }
    },
    {
      "action": "path",
      "options": {
        "path": "/contact-list"
      }
    }
  ]
}
```

## Setting Up Site Navigation in the IDE

### Where to Configure Site Navigation

1. **Open App Settings** in the BetterForms IDE
2. **Navigate to Environment section**
3. **Find the Navigation tab**
4. **Configure your navigation schema**

### Navigation Slugs (URL Mapping)

First, set up navigation slugs to map friendly URLs to page IDs:

```json
{
  "default": {
    "id": "36D74465-3F11-4CE4-A0FD-370D78C98B86"
  },
  "dashboard": {
    "id": "633D7D10-F8AD-4B6E-8D86-BDC8038D6E91"
  },
  "contacts": {
    "id": "A1B2C3D4-E5F6-7890-1234-567890ABCDEF"
  },
  "settings": {
    "id": "F1E2D3C4-B5A6-9876-5432-10FEDCBA9876"
  }
}
```

**Benefits of Navigation Slugs:**

* **Clean URLs:** `/dashboard` instead of `/form/633D7D10-F8AD-4B6E-8D86-BDC8038D6E91`
* **Easy Updates:** Change the page ID in one place to update all references
* **User-Friendly:** URLs are easier to understand and remember

### Navigation Menu Schema

The navigation menu is defined as an array of objects in the **Menu Schema** section:

```json
[{
  "sectionLabel": "Main Menu",
  "subs": [{
    "label": "Dashboard",
    "icon": "fa fa-home",
    "path": "/dashboard"
  }, {
    "label": "Contacts",
    "icon": "fa fa-users",
    "path": "/contacts"
  }, {
    "label": "Settings",
    "icon": "fa fa-cog",
    "path": "/settings"
  }]
}]
```

### Navigation Menu Structure

**Top Level Properties:**

* `sectionLabel`: Section title (not clickable)
* `subs`: Array of menu items
* `styleClassesSection`: CSS classes for the section

**Menu Item Properties:**

* `label`: Display text
* `icon`: Font Awesome icon class
* `path`: Navigation path (corresponds to slugs)
* `actions`: Alternative to path for complex behaviors
* `visible`: Boolean or `visible_calc` for conditional display

## Advanced Navigation Examples

### Dropdown Menus

Create hierarchical navigation with nested menus:

```json
[{
  "sectionLabel": "Main Menu",
  "subs": [{
    "label": "Dashboard",
    "icon": "fa fa-home",
    "path": "/dashboard"
  }, {
    "label": "Contacts",
    "icon": "fa fa-users",
    "subs": [{
      "label": "View All Contacts",
      "icon": "fa fa-list",
      "path": "/contacts"
    }, {
      "label": "Add New Contact",
      "icon": "fa fa-plus",
      "path": "/contact-new"
    }, {
      "divider": true
    }, {
      "label": "Import Contacts",
      "icon": "fa fa-upload",
      "path": "/contact-import"
    }]
  }]
}]
```

### Action-Based Navigation Items

Use actions instead of direct navigation for complex behaviors:

```json
[{
  "sectionLabel": "Main Menu",
  "subs": [{
    "label": "Logout",
    "icon": "fa fa-sign-out",
    "actions": [{
      "action": "authLogout"
    }, {
      "action": "path",
      "options": {
        "path": "/login"
      }
    }]
  }]
}]
```

### Conditional Navigation

Show navigation items based on user permissions:

```json
[{
  "sectionLabel": "Main Menu",
  "subs": [{
    "label": "Admin Panel",
    "icon": "fa fa-shield",
    "path": "/admin",
    "visible_calc": "app.user.role === 'admin'"
  }]
}]
```

### Navigation with Badges

Add dynamic badges to navigation items:

```json
[{
  "sectionLabel": "Main Menu",
  "subs": [{
    "html": "<a href=\"/#/messages\" title=\"Messages\">\n    <i class=\"fa fa-envelope\"></i> Messages\n    <span class=\"pull-right badge badge-danger\">{{app.unreadCount}}</span>\n</a>"
  }]
}]
```

## URL Structure and Query Parameters

### BetterForms URL Structure

```
https://yourdomain.fmbetterforms.com/#/dashboard?id=123&mode=edit
```

**Components:**

* `https://yourdomain.fmbetterforms.com` - Your domain
* `#/dashboard` - Navigation slug
* `?id=123&mode=edit` - Query parameters

### Working with Query Parameters

**In FileMaker Scripts:** Access query parameters via the `$$BF_Query` global variable:

```javascript
// In your onFormRequest hook
Set Variable $contactId = JSONGetElement($$BF_Query, "id")
Set Variable $mode = JSONGetElement($$BF_Query, "mode")
```

**In JavaScript/HTML:**

```javascript
// Using BetterForms utility function
const contactId = BF.getQueryParam('id');
const mode = BF.getQueryParam('mode');
```

## IDE Navigation Configuration Workflow

### Step 1: Plan Your Navigation Structure

1. **List all pages** in your app
2. **Group related pages** under logical sections
3. **Determine hierarchy** (which pages need submenus)
4. **Consider user roles** (which pages need conditional access)

### Step 2: Set Up Navigation Slugs

1. **Go to App Settings → Navigation**
2. **Find the Slug Names section**
3. **Add entries** for each page:

   ```json
   {
     "dashboard": { "id": "your-page-id" },
     "contacts": { "id": "your-page-id" },
     "settings": { "id": "your-page-id" }
   }
   ```

### Step 3: Configure Menu Schema

1. **In the Menu Schema section**
2. **Build your navigation structure**:

   ```json
   [{
     "sectionLabel": "Main Menu",
     "subs": [
       // Your menu items here
     ]
   }]
   ```

### Step 4: Test Navigation

1. **Save your changes**
2. **Test each navigation item**
3. **Verify paths resolve correctly**
4. **Check conditional visibility**

## Best Practices

### 1. **Consistent Navigation Structure**

* Keep navigation consistent across all pages
* Use familiar icons and terminology
* Group related functionality together

### 2. **User-Friendly URLs**

* Use descriptive navigation slugs
* Avoid exposing internal page IDs
* Keep URLs short and memorable

### 3. **Responsive Design**

* Consider mobile navigation experience
* Use appropriate icons for touch interfaces
* Test navigation on different screen sizes

### 4. **Performance Optimization**

* Minimize navigation complexity
* Use conditional visibility judiciously
* Consider caching navigation data

## Integration with FileMaker

### Navigation-Triggered Scripts

Navigation can trigger FileMaker scripts using actions:

```json
{
  "label": "Generate Report",
  "icon": "fa fa-file-pdf",
  "actions": [{
    "action": "runUtilityHook",
    "options": {
      "type": "generateReport",
      "reportType": "monthly"
    }
  }]
}
```

### Dynamic Navigation Updates

Update navigation based on FileMaker data:

```json
{
  "label": "Orders",
  "icon": "fa fa-shopping-cart",
  "path": "/orders",
  "visible_calc": "app.user.permissions.includes('view_orders')"
}
```

## Troubleshooting Common Issues

### Navigation Not Working

* Check that navigation slugs are properly configured
* Verify page IDs are correct
* Ensure JSON syntax is valid

### Pages Not Loading

* Confirm target pages exist
* Check page authentication settings
* Verify navigation paths match slug names

### Conditional Navigation Issues

* Test `visible_calc` expressions
* Verify app model data is available
* Check for JavaScript syntax errors

## Next Steps

Now that you understand navigation, you can:

* **Implement data tables** - See [4.3 Displaying Data in Tables](/getting-started/ide-quick-tour/4.-common-customizations-and-expanding-your-app/4.3-displaying-data-in-tables-page-builder-and-element-config.md)
* **Style your navigation** - See [4.4 Basic App Styling](/getting-started/ide-quick-tour/4.-common-customizations-and-expanding-your-app/4.4-basic-app-styling-site-styling-ui.md)
* **Learn about authentication** - See [Authentication](/reference/authentication.md)

{% hint style="info" %}
**URL Best Practice:** Always use navigation slugs instead of direct page IDs for better maintainability and user experience.
{% endhint %}
