You are viewing beta documentation for Navigation 4.x.
Migrations

Migrating from FreeNav

If your Craft site runs FreeNav (opens new window) (justinholtweb/craft-free-nav), Navigation can copy menus and node structure without modifying FreeNav data — similar to Formie's plugin migrations (opens new window).

Prerequisites

  1. Install both FreeNav and Navigation on the same Craft site.
  2. Back up your database and project config.
  3. Run the migration on staging first.

Control panel

  1. Go to Navigation → Settings.
  2. Under Migrations, choose FreeNav.
  3. Select the menus to migrate (or choose All).
  4. Optionally enable Skip existing handles if you do not want to overwrite menus that already exist in Navigation.
  5. Click Migrate Menus and review the per-menu output log. Click Done when finished.

Console

# All FreeNav menus
php craft navigation/migrate/free-nav

# Specific handle(s)
php craft navigation/migrate/free-nav --handle=mainMenu,footerMenu

# Skip menus whose handles already exist in Navigation
php craft navigation/migrate/free-nav --skip-existing

What is migrated

FreeNavNavigation
Menus and handlesMenu name, handle, site settings
Entry, category, asset, product nodesMatching element-backed node types
Custom URL nodesCustom node type
Passive nodesPassive node type
Site nodesSite node type
Nested structureParent/child tree preserved
Node CSS classes, new windowclasses, newWindow, customAttributes
Multi-site propagationPer-site menu settings

If an element-backed node no longer has a resolvable linked element, it is converted to a Custom URL node and a warning is logged.

Manual follow-up

FreeNav featureNotes
Conditional visibilityStored in node data as migratedFreeNavVisibilityRules but not enforced — rebuild with templates or custom logic
Icon / badge fieldsNot migrated — map to node custom fields on the menu field layout
Template render presetsReplace craft.freenav.render() with Navigation templates
REST / GraphQL clientsUpdate to Navigation's GraphQL or headless APIs

Handle collisions

When a Navigation menu with the same handle already exists, the migrator creates a new menu with a numeric suffix (for example mainMenu1).

Template mapping

{# FreeNav #}
{{ craft.freenav.render('mainMenu') }}

{# Navigation #}
{{ craft.navigation.render('mainMenu') }}