Esri's Global Nav is a small JavaScript component that enables developers at Esri to quickly create top-level navigation (and footer) in their projects that is accessible, localizable, and on-brand. It comes in two flavors: web mode and app mode which are intended for use in marketing and SaaS applications, respectively.
Installation
You can install the global nav component with npm:
npm install --save Esri/global-nav
To use a particular version, add it to the end:
npm install --save Esri/global-nav#v1.2.1
If you're not using npm, simply download the latest release.
If you'd like to install the Global Nav as a submodule you can do that, too:
git submodule add git@github.com:Esri/global-nav.git ./esri-global-nav
Use
Import
First, you need to import the global nav library into your page. The best way to do this will vary based on your toolchain and build process. For static html pages, you can simply add a link to the JS and CSS files:
<!-- in the HEAD tag -->
<link rel="stylesheet" href="./esri-global-nav.css">
<!-- before the end of BODY tag -->
<script src="./path/to/esri-global-nav.js"></script>
If you're using a module system for your JS, the library can be imported via CommonJS:
var globalNav = require('esri-global-nav')
Or AMD (Dojo define syntax):
define([
"esri-global-nav/dist/esri-global-nav.js"
], function (globalNav) {
return {
init: function () {
var navStructure = {} // See below for an example
globalNav.create(navStructure);
}
}
});
Initialize
Once you have a script imported, the global nav needs to be passed two things to get set up:
- A JavaScript object with the structure of your navigation
- A DOM Node which will act as the container for the built navigation
The basic stucture of the options object would look something like this (abbreviated for clarity):
{
header: {
theme: 'web',
brand: {
label: 'Esri Global',
image: './img/gnav-esri-logo-globe-tm.svg',
href: 'https://www.esri.com/',
width: 80,
height: 30
},
menus: [
[
{
label: 'ArcGIS',
menus: [
{
label: 'About ArcGIS',
href: 'https://www.esri.com/arcgis/about-arcgis',
data: {
this: true,
that: true,
other: true,
thing: true
},
newContext: true
},
{
label: 'Products',
href: 'https://www.esri.com/products'
},
...
],
tiles: [
{
label: 'ArcGIS Pro',
href: 'https://www.esri.com/arcgis/products/arcgis-pro/Overview',
icon: [
'M15 36.1h-2.1v-3.2H15v-.8H1.5a.6.6 0 0 1-.6-.6v-26a.6.6 0 0 1 .6-.6h38a.6.6 0 0 1 .6.6V23h.8V5.5a1.401 1.401 0 0 0-1.4-1.4h-38A1.401 1.401 0 0 0 .1 5.5v26a1.401 1.401 0 0 0 1.4 1.4h10.6v3.2H8v.8h7z',
'M43.9 41.1V26.5a1.401 1.401 0 0 0-1.4-1.4h-24a1.401 1.401 0 0 0-1.4 1.4v14.6h-3V43a1.902 1.902 0 0 0 1.9 1.9h29a1.902 1.902 0 0 0 1.9-1.9v-1.9zm-26-14.6a.6.6 0 0 1 .6-.6h24a.6.6 0 0 1 .6.6v14.6h-1.2v-14H19.1v14h-1.2zm2 14.6V27.9h21.2v13.2zM46.1 43a1.101 1.101 0 0 1-1.1 1.1H16a1.101 1.101 0 0 1-1.1-1.1v-1.1h13.164A1.495 1.495 0 0 0 29.5 43h3a1.492 1.492 0 0 0 1.433-1.1H46.1z',
'M34 30.9h2.884l-5.736 5.089-4.214-3.029-4.239 4.981.61.518 3.761-4.419 4.135 2.971 5.899-5.233V34h.8v-3.9H34v.8zm3.9-7.9V7.1H3.1v22.8H15v-.8h-1.546c-.021-.08-.04-.152-.044-.136a1.58 1.58 0 0 1 .462-.86 2.677 2.677 0 0 0 .486-.763 1.466 1.466 0 0 0-.056-.93 1.807 1.807 0 0 1-.099-.5c0-1.054-1.089-1.308-1.884-1.494-.356-.083-.894-.21-.97-.362-.398-.796-.04-1.212.628-1.878a2.653 2.653 0 0 0 1.03-1.831c0-.572-.31-1.512-1.137-1.595a2.261 2.261 0 0 0-1.157.19 1.825 1.825 0 0 1-.738.166c-.298 0-.618-.175-.618-.436a1.857 1.857 0 0 1 .31-.918 2.578 2.578 0 0 0 .407-1.298 3.17 3.17 0 0 0-.132-.85 2.413 2.413 0 0 1-.106-.645 1.044 1.044 0 0 1 .976-1.098c.477 0 .705.368 1.086 1.05a1.876 1.876 0 0 0 1.786.925c1.377 0 2.255-1.584 2.255-2.675a.707.707 0 0 1 .619-.736 1.176 1.176 0 0 1 .715.338 1.923 1.923 0 0 0 1.199.5c.98 0 1.386-.72 1.745-1.356a2.536 2.536 0 0 1 .899-1.087A2.644 2.644 0 0 0 22.31 7.9H37.1v9.362c-.116.067-.236.133-.343.201a1.916 1.916 0 0 1-1.076.414c-.164 0-.335-.012-.511-.024a4.623 4.623 0 0 0-1.42.07c-.321.089-.708.219-1.063.339a9.223 9.223 0 0 1-.885.274 2.082 2.082 0 0 0-.91.284 1.495 1.495 0 0 1-.556.2 2.912 2.912 0 0 1-1.845-.81 2.09 2.09 0 0 1-.425-.628c-.231-.445-.52-1-1.276-1a1.856 1.856 0 0 0-1.495 1.031c-.3.428-.502.691-.839.691a1.58 1.58 0 0 1-.555-.143 2.268 2.268 0 0 0-.84-.197c-.678 0-1.434.475-1.434 1.156v1.168c0 .312-.17.499-.472.8a1.88 1.88 0 0 0-.707 1.37 1.232 1.232 0 0 0 .343.781l.321-.239.267-.31c-.092-.12-.13-.173-.13-.232 0-.314.17-.5.473-.804a1.878 1.878 0 0 0 .705-1.366V19.12c0-.147.328-.355.635-.355a1.575 1.575 0 0 1 .553.143 2.283 2.283 0 0 0 .841.196 1.854 1.854 0 0 0 1.494-1.03c.302-.428.504-.691.84-.691.239 0 .33.114.567.569a2.77 2.77 0 0 0 .606.86 3.635 3.635 0 0 0 2.373 1.008 2.08 2.08 0 0 0 .912-.284 1.498 1.498 0 0 1 .554-.2 4.634 4.634 0 0 0 1.14-.317c.342-.115.712-.24 1.02-.325a3.843 3.843 0 0 1 1.155-.043c.194.013.383.025.564.025a2.511 2.511 0 0 0 1.419-.485V23zM20.734 10.12a3.23 3.23 0 0 0-1.215 1.396c-.351.624-.557.95-1.047.95a1.178 1.178 0 0 1-.717-.338 1.92 1.92 0 0 0-1.198-.5 1.5 1.5 0 0 0-1.418 1.536c0 .643-.567 1.875-1.455 1.875a1.105 1.105 0 0 1-1.106-.548c-.373-.669-.796-1.427-1.766-1.427a1.841 1.841 0 0 0-1.776 1.897 3.159 3.159 0 0 0 .131.848 2.405 2.405 0 0 1 .107.648 1.855 1.855 0 0 1-.31.915 2.584 2.584 0 0 0-.407 1.3 1.327 1.327 0 0 0 1.417 1.236 2.573 2.573 0 0 0 1.03-.221 1.45 1.45 0 0 1 .784-.14c.278.028.418.528.418.8 0 .47-.368.839-.795 1.264-.648.647-1.454 1.451-.778 2.802.245.489.856.632 1.504.783.876.205 1.266.357 1.266.715a2.482 2.482 0 0 0 .131.725.896.896 0 0 1 .067.443 2.159 2.159 0 0 1-.353.523 2.228 2.228 0 0 0-.638 1.361.59.59 0 0 0 .018.136H3.9V7.9h17.602c.139.9.089 1.756-.768 2.22z'
]
},
...
]
},
...
]
],
search: {
label: 'Search',
dialog: {
action: 'https://pages.codehub.esri.com/marketing/esri-search-page/',
label: 'Esri',
'submitLabel': 'Search',
'cancelLabel': 'Cancel',
'queryLabel': 'Search Esri.com'
}
},
apps: {
label: 'Applications',
icons: [
{
abbr: "APP",
image: "http://www.arcgis.com/home/js/arcgisonline/sharing/dijit/css/images/app-icons/appstudio.png",
label: "AppStudio for ArcGIS",
url: "//appstudiodev.arcgis.com/apps.html"
},
...
]
},
account: {
label: 'Account Profile',
controls: {
signin: 'Sign In',
signout: 'Sign Out',
switch: 'Switch Account'
},
menus: [
{
label: 'Profile & Settings',
href: '#user-menu-link-1'
},
{
label: 'My Esri',
href: '#user-menu-link-2'
},
{
label: 'Training',
href: '#user-menu-link-3'
},
{
label: 'Community & Forums',
href: '#user-menu-link-4'
}
],
user: {
name: 'Cesar Marrujo',
id: 'iamoktatester@gmail.com',
group: 'Riverside City Mgmt.',
image: '//placehold.it/300x300'
}
}
},
// Object representing the structure of the entire footer (optional)
footer: {
hideMenus: false,
label: 'Esri',
brand: {
label: 'Esri: The Science of Where',
href: 'https://www.esri.com/about-esri',
viewBox: '0 0 114 90',
path: './img/gnav-tsow-frame.svg'
},
menu: {
label: 'Esri Sites',
menu: [
{
label: 'ArcGIS',
menu: [
{
label: 'About ArcGIS',
href: 'https://www.esri.com/arcgis/about-arcgis'
},
...
]
},
...
]
},
social: {
label: 'Social Media',
menu: [
{
label: 'Facebook',
href: 'https://www.facebook.com/esrigis',
image: {
viewBox: '0 0 38 38',
path: ['M38 38V0H0v38h17.2V21.9H14v-5.7h3.2v-3.7c0-2.6 1.2-6.7 6.7-6.7h4.9v5.5h-3.6c-.6 0-1.4.3-1.4 1.5v3.3h5.1l-.6 5.7h-4.5v16.1H38z']
}
},
...
]
},
info: {
label: 'Additional Links',
menu: [
{
label: 'Privacy',
href: 'https://www.esri.com/legal/privacy'
},
...
]
},
language: {
label: 'Switch Languages',
buttonLabel: 'United States (English)',
submitLabel: 'Change',
greetingLabel: 'Hello!',
messageLabel: 'You are seeing the English page. Is this correct?',
closeLabel: 'Close Navigation',
optionsLabel: 'Desired Language',
options: [
{
label: 'English',
value: '#the-english-page'
},
...
]
}
}
};
After you've defined the structure of your navigation, just call globalNav.create
to start up your navigation, passing in the options and the containers like so:
esriGlobalNav.create({headerElm: '.esri-header-barrier', footerElm: '.esri-footer-barrier', menuData});
For a complete example, you can reference the demo.
Events
The global nav dispatches custom events to each of its modules (Header and Footer).
globalNav.create(yourGlobalNavStructure);
var esriHeader = document.querySelector('.esri-header-barrier');
esriHeader.addEventListener("header:click:search", function () { ... });
Important events:
header:click:account
header:click:search
header:click:signin
header:click:signout
header:click:switch
header:menu:toggle
Advanced
Opening Links in a New Tab
Links, within a menu, can be configured to open in a new tab. As of now, this only works for links within dropdown submenus.
yourGlobalNavStructure = {
theme: 'web',
menus: [[
{
label: 'Special Page',
href: '../Special.html',
openInNewTab: true // boolean
}
]]
}
Adding Data Attributes to Links
Menu links can receive data attributes too. Here, we create a special page link that has an an attribute of "data-id" that's equal to "1" and "data-show-link" that's equal to "true". As of now, this only works for links within dropdown submenus
yourGlobalNavStructure = {
theme: 'web',
menus: [[
{
label: 'Special Page',
href: '../Special.html',
data: {
'id': "1",
'show-link': "true"
}
}
]]
}
Always Display the Hamburger
header: {
collapseMenus: [true, false]
Using Inline Search
Inline search is a powerful way to supercharge the search experience for your users. It gives users the ability to view search results & suggestions in a dropdown without having to navigate away from their current content.
//_______________________________________________________________________________
// - To use inline search, set the parameter inline to true within the search object
//-------------------------------------------------------------------------------
search: {
inline: true
//_______________________________________________________________________________
// - Setup an event to listen for typing within the search input
//-------------------------------------------------------------------------------
document.querySelector(".esri-header-barrier").addEventListener('header::search:typing', function (e) {
// e.detail will contain the current value of the search input
if (e.detail.length >= 2) {
// ... Fetch search suggestions or results here
}
});
//_______________________________________________________________________________
// - Pass an array of objects containing a header, footer, and array of links to populate suggestions
// - Additionally, you'll need to pass in a string for the see all results link
//-------------------------------------------------------------------------------
const event = document.createEvent("CustomEvent");
event.initCustomEvent('header:search:update:suggestions', true, true, {
seeAllResultsString: "See all results for",
suggestions: [
{
header: "Content",
links: [
{text: "Sudo Polarized Data", href: "https://example.com?q=Sudo Polarized Data"},
{text: "Data Aardvarks", href: "https://example.com?q=Data Aardvarks"},
{text: "Polymorphic Data Streams", href: "https://example.com?q=Polymorphic Data Streams"}
],
footer: {text: "View all content results", href: "https://arcgis.com"}
},
{
header: "Groups",
links: [
{text: "Group Data", href: "https://example.com?q=Group Data"},
{text: "Concentrated Geometric Data", href: "https://example.com?q=Concentrated Geometric Data"},
{text: "Milk and Data" , href: "https://example.com?q=Milk and Data"}
],
footer: {text: "View all groups results", href: "https://arcgis.com"}
}
]
});
document.querySelector(".esri-header-inlineSearch").dispatchEvent(event);
//_______________________________________________________________________________
// - Sending an empty array will trigger an empty state
//-------------------------------------------------------------------------------
event.initCustomEvent('header:search:update:suggestions', true, true, {
suggestions: []
});
Using Inline Title
Inline title provides users whith a way to edit brand text. It was designed for use within mapping applications like map and scene viwer.
//_______________________________________________________________________________
// - To use inline title, set the parameter editTitle to true within the brand object
//-------------------------------------------------------------------------------
// The inline title properties in brand are editTitle, titleFontSize, and maxViewWidth
header: {
theme: 'app',
brand: {
label: 'My Mapping App',
editTitle: true, // Activates the inline-title
titleFontSize: 18, // Lets apps set the font size for the title (optional)
maxViewWidth: 25, // Helps Apps adjust the max width of the title (optional)
brandText: 'My Mapping App',
topStripe : '#e8912e'
},
//_______________________________________________________________________________
// - Setup an event to listen for header:title:save
//-------------------------------------------------------------------------------
var header = document.querySelector('.esri-header-barrier');
header.addEventListener("header::title:save", (result) => {
// Create and dispatch event to update the inlinte title with a new value
var event = document.createEvent("CustomEvent");
event.initCustomEvent("header:update:inlineTitle", true, true, {
label: result.detail,
maxWidth: 380,
brandText: result.detail,
});
document.querySelector(".esri-header-inline-title").dispatchEvent(event);
});
Configuring the App Launcher
To work with the standard set of apps from ArcGIS Online use the AGO Webworker Interface: https://github.com/ArcGIS/AGO-Webworker-Interface
//_______________________________________________________________________________
// - Before apps are loaded, we want to initialize the apps component with a loading state
// -- Dispatch the event to update apps in the header
//-------------------------------------------------------------------------------
var event = document.createEvent("CustomEvent");
event.initCustomEvent("header:update:apps", true, true, {
label: "Your Apps",
disableDragDrop: false,
image: [ // - Grid Icon
'M0 0h3v3H0zM8 0h3v3H8zM16 0h3v3h-3zM0 8h3v3H0zM8 8h3v3H8zM16 8h3v3h-3zM0 16h3v3H0zM8 16h3v3H8zM16 16h3v3h-3z'
],
loading: true // - Loading state
});
document.querySelector(".esri-header-apps").dispatchEvent(event);
//_______________________________________________________________________________
// - When apps are available, update the header with them
// -- The app launcher requires strings as well; contained within the text parameter
// -- Note: If you're using AGO Webworker Interface, it will give you the majority of this data
//-------------------------------------------------------------------------------
event.initCustomEvent("header:update:apps", true, true, {
label: 'Applications',
disableDragAndDrop: false,
displayIntro: true,
ieVersion: null,
text: {
title: "App Launcher",
clear: "Clear",
confirm: "Got it.",
dragAppsHere: "Drag apps here that you don't use very often.",
intro: "Drag and drop your favorite apps in any order to customize your app launcher",
removed: "This app is no longer available.",
removedMessage: "Removed app",
showMore: "Show More"
},
image: [
'M0 0h3v3H0zM8 0h3v3H8zM16 0h3v3h-3zM0 8h3v3H0zM8 8h3v3H8zM16 8h3v3h-3zM0 16h3v3H0zM8 16h3v3H8zM16 16h3v3h-3z'
],
primary: [
{
abbr: "APP", // - This is only used if a placeholderIcon is utilized; see the next app for an example
image: "https://www.example.com/url-to-app-icon.png", // - The app icon
label: "AppStudio for ArcGIS", // - Text that appears below the app icon
url: "//appstudiodev.arcgis.com/apps.html", // - Where the app redirects to
canAccess: true, // - If set to false, the app will be placed in a disabled state
itemId: "131049582192" // - ItemId is the unique id to identify apps; used when saving the app sorting order for users
},
{
abbr: "Studio", // - This text will be centered on top of the placeHolder icon
placeHolderIcon: "https://www.example.com/url-to-your-placeholder-icon.png",
image: null,
label: "Studio for ArcGIS",
url: "//appstudiodev.arcgis.com/apps.html",
canAccess: true,
itemId: "131049582193"
}
],
secondary: [
{
abbr: "APP",
image: "https://www.example.com/url-to-app-icon.png",
label: "AppStudio for ArcGIS",
url: "//appstudiodev.arcgis.com/apps.html",
canAccess: true,
itemId: "131049582195"
}
]
)};
Configuring the shopping cart
The Global Navigation now features a shopping cart integration system, which gives users the ability to view, add, and remove items from their shopping cart. The shopping cart icon displays the number of items in the cart, and also uses and interactive animation feature to give visual feedback as items are added, or removed.
//_________________________________________________________________________________________________
// - The shopping cart listens for the following events to add, and remove cart items respectively.
// -- It receives the target element, and the number of items to add/remove from the cart as params.
//_________________________________________________________________________________________________
header:shoppingcart:add
header:shoppingcart:remove
Configuring the column based menu
The global navigation now features a new column based layout. This new feature supports both single, and structured menu types. You can specify up to three columns per menu as well as the type of menu to render in each column.
//____________________________________________________________________________________________
// - In the 'cols' array you create an object representation of the menu for each column
// -- You can configure the menu in each column as either a 'single' or 'structured' menu type
// -- Note: You can also specify to have a right 'border' to seperate the individual columns
//--------------------------------------------------------------------------------------------
{
label: 'Products',
cols: [
{
type: 'single',
border: 'true',
items: [
{
heading: 'CAPABILITIES',
label: 'Mapping & Location Enablement',
href: 'https://www.esri.com/en-us/location-intelligence'
},
{
label: 'Field Operations',
href: 'https://www.esri.com/en-us/arcgis/analytics/overview'
},
{
label: 'Spatial Analysis & Data Science',
href: 'https://www.esri.com/en-us/location-intelligence'
},
{
label: 'Imagery & Remote Sensing',
href: 'https://www.esri.com/en-us/location-intelligence'
}
]
},
{
type: 'structured',
border: 'false',
items: [
{
heading: 'CORE PRODUCTS',
label: 'ArcGIS Online',
href: 'https://www.esri.com/en-us/location-intelligence',
description: 'Complete SaaS mapping platform'
},
{
label: 'ArcGIS Pro',
href: 'https://www.esri.com/en-us/arcgis/analytics/overview',
description: 'Next generation desktop GIS'
},
{
label: 'ArcGIS Enterprise',
href: 'https://www.esri.com/en-us/location-intelligence',
description: 'Flexible mapping server software'
}
]
},
{
type: 'structured',
border: 'false',
items: [
{
heading: 'FEATURED PRODUCTS',
label: 'ArcGIS Urban',
href: 'https://www.esri.com/en-us/location-intelligence',
description: 'Smart city planning for urban development'
},
{
label: 'ArcGIS Business Analyst',
href: 'https://www.esri.com/en-us/arcgis/analytics/overview',
description: 'Business and market intelligence'
}
]
}
]
}