Importing Menus
The Menus import creates and updates your store's navigation menus (the Main menu, Footer menu, and any custom menus) from a CSV/Excel file, a Google Sheet, or directly from another connected store. A menu is a tree of links, so the import uses one row per link with a level column that says how deep it sits. Menus are matched by handle, so running the same file twice rebuilds the same menu instead of creating a duplicate.
For the wizard itself — uploading, mapping, dry runs, schedules — see Importing into EcomSolo.
How a menu is laid out in a spreadsheet
Each menu is a group of consecutive rows that share the same Handle. The first row of the group carries the menu's Title; every row carries one item (link), and the item's Level places it in the tree:
- Level 1 — a top-level item.
- Level 2 — a child of the most recent level-1 item above it.
- Level 3 — a child of the most recent level-2 item above it.
Shopify menus nest up to three levels. A menu with a title but no item rows is imported as an empty menu.
Columns
| Column | Notes |
|---|---|
| Handle | The menu's unique handle (e.g. main-menu, footer). Required — it's the identity used to match and create menus. Repeat it on every row of the same menu. |
| Title | The menu's display name (e.g. Main menu). Required by Shopify on every menu. Put it on the first row of the group. |
| Item level (1-3) | The nesting depth of this row's link. Blank counts as level 1. |
| Item title | The link's visible label. |
| Item type | What the link points to (see below). A row with a URL but no type is treated as a plain link. |
| Item URL | The destination for HTTP links — a relative path (/collections/sale) or an absolute URL. |
| Item resource id / GID | For links that point to a specific product, collection, page, blog, or article — the resource's numeric id or full GID. |
| Item tags | Optional filter tags for CATALOG / collection links (comma-separated). |
Item types
Item type is one of Shopify's menu link types:
- HTTP — a plain link to any URL (uses Item URL).
- FRONTPAGE — the storefront home page.
- PAGE, PRODUCT, COLLECTION, BLOG, ARTICLE — a link to that specific resource (uses Item resource id).
- COLLECTIONS — the "all collections" page.
- CATALOG — a filtered collection (uses Item tags).
- SEARCH, SHOP_POLICY — the search page / a store policy.
For a resource link you can supply just the numeric id — EcomSolo expands it to
the full Shopify GID for you (123 with type PRODUCT becomes
gid://shopify/Product/123). A full GID is accepted as-is.
How menus are matched
Every menu is matched to an existing one by handle in the target store. What happens on a match depends on the operation you pick for the run:
| Operation | On an existing menu | On a new handle |
|---|---|---|
| Upsert (default) | Replaces its items, updates title | Creates it |
| Create | Fails the group | Creates it |
| Update | Replaces its items, updates title | Fails the group |
| Merge | Replaces its items, updates title | Fails the group |
| Delete | Deletes it | Skips the group |
Because an update replaces the whole item tree, your file should describe the menu as you want it to end up — anything you leave out is removed from that menu. The dry run shows the create / update / delete split before anything is written, and if a menu exists on Shopify but hasn't synced into EcomSolo yet, the import still recognizes the collision and updates it rather than failing.
Deleting menus
Choose the Delete operation to remove menus. A delete file needs only the Handle of each menu to remove; item rows are ignored. Deletes are permission-gated (navigation write access) and irreversible, so the dry run always shows the count first. A handle that no longer exists is quietly skipped, so re-running the same delete file is safe (idempotent).
Shopify's default menus (the Main menu and Footer menu) can't be deleted — Shopify rejects the row with "Default menu cannot be deleted", which the report shows verbatim. Edit those menus with an Update/Upsert instead.
Importing from another store
On the wizard's Source step, pick From another store to copy menus from a connected store — no file needed. Each source menu comes across as its full set of leveled rows, matched by handle. Combined with a schedule this becomes a recurring one-way menu sync.
One caveat worth knowing: menus made of plain links (HTTP) and storefront
targets (FRONTPAGE, SEARCH, policies) copy across cleanly. Items that point
to a specific product, collection, page, or article reference the source
store's ids, which don't exist on a different store — those links need
re-pointing on the target. Footer-style link menus are the sweet spot for
store-to-store; a Main menu full of collection links is best rebuilt from a file.
Results and freshness
Menus you create or update take effect in Shopify immediately, and EcomSolo's Menus dashboard refreshes within seconds of the run.
Sample file
A ready-to-run example ships as menus-sample.csv — a three-level menu plus a
flat footer menu:
Handle,Title,Item level (1-3),Item title,Item type,Item URL
wow-main-menu,Wow Main menu,1,Home,HTTP,/
wow-main-menu,Wow Main menu,1,Shop,HTTP,/collections/all
wow-main-menu,Wow Main menu,2,Men,HTTP,/collections/men
wow-main-menu,Wow Main menu,3,Shirts,HTTP,/collections/mens-shirts
wow-main-menu,Wow Main menu,2,Women,HTTP,/collections/women
wow-main-menu,Wow Main menu,1,About,HTTP,/pages/wow-about
wow-footer,Wow Footer,1,Contact,HTTP,/pages/wow-contact
wow-footer,Wow Footer,1,Shipping,HTTP,/pages/wow-shipping
Dry run: will create 2 menus (or update for handles that already exist).
Troubleshooting
| Error in the report | What it means / what to do |
|---|---|
row requires a Handle | Every row needs the menu's handle — repeat it on each item row. |
row requires a Title | Shopify requires a title on every menu; put it on the first row of the group. |
menu item '…' needs a Type (or a URL for a plain link) | An item row has a title but no way to know where it links — set an Item type, or give it an Item URL for a plain link. |
a menu item is missing its Title | An item row has a type/URL but no label. |
… access scope / missing permission | The store isn't connected with navigation write access — reconnect it from its settings, then re-run. |
FAQ
Will re-importing create duplicates? No — menus match by handle, and the default Upsert operation updates the same menu in place.
Does updating a menu keep its old links? No — an update replaces the menu's items with what's in your file. Include every link you want the menu to have.
How deep can menus go? Three levels, matching Shopify's own menu editor.
Can I delete menus? Yes — run the file with the Delete operation and a column of handles. It's permission-gated and irreversible, and missing handles are skipped. Shopify's default Main and Footer menus can't be deleted. See Deleting menus.