The @uol-header-local-navigation presents a set of site specific top level links allowing visitors to navigate the local site.
The purpose of this component is to provide consistent navigation throughout the site allowing users to get to key areas within the site easily.
The local navigation must remain consistent throughout the site, ie. if two pages are on the same domain or subdomain the navigation should always be the same.
Examples:
must have the same navigation
must have the same navigation
The local navigation should always start with a “Home” link that returns the user to the site root.
The local navigation supports a single level of sub-navigation to support groups of related links. Example
We do not recommend having more than one set of sub-navigation within the local navigation, as illustrated.
The sub-navigation items may also include CTAs (Calls to action). These items are styled differently and should be located at the end of the sub-navigation group.
Once users have navigated to a section of the site using the local navigation, additional navigation can be provided using the @uol-section-nav.
If the current page matches a link from the local navigation, the matching navigation link should be set as “current”: true.
Example:
{
"title": "Home",
"url": "/",
"current": true
},
The Local navigation: Highlight Active Page variant shows how one item (other than the home page) are given this value. Specifying “current” as true adds aria-current=”page” on to the link (a tag). Setting this parameter also changes the style of this link to signify this is the current page.
When implementing this header, ensure that aria-current=”page” is added to the link representing the current page and only this page.
This also helps Assistive Technology users know that the link will not take them to a different page.
Only navigation items within the sub-navigation may use “cta”: true. Items identified as CTAs should be grouped together at the end of a sub-navigation group. See component example context for illustration.
{% if items.length %}
<nav class="uol-header-local-navigation-wrapper uol-content-container" aria-label="Site navigation">
<ul class="uol-header-local-navigation">
{% for item in items %}
<li class="uol-header-local-navigation__item {{ 'uol-header-local-navigation__item--parent' if item.items.length }}" data-label="{{ item.title }}">
{% if item.url %}
<a class="uol-header-local-navigation__link" href="{{ item.url }}" {% if item.current %}aria-current="page"{% endif %}>
{% endif %}
{{ item.title }}
{% if item.url %}
</a>
{% endif %}
{% if item.items.length %}
<ul class="uol-header-local-navigation__sub-nav" data-title="{{ item.title }}">
{% for item in item.items %}
<li class="uol-header-local-navigation__item {{ 'uol-header-local-navigation__item--cta' if item.cta }}">
{% if item.url %}
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="{{ item.url }}" {% if item.current %}aria-current="page"{% endif %}>
{% endif %}
{{ item.title | safe }}
{% if item.url %}
</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
</nav>
{% endif %}
<nav class="uol-header-local-navigation-wrapper uol-content-container" aria-label="Site navigation">
<ul class="uol-header-local-navigation">
<li class="uol-header-local-navigation__item " data-label="Home">
<a class="uol-header-local-navigation__link" href="/" aria-current="page">
Home
</a>
</li>
<li class="uol-header-local-navigation__item uol-header-local-navigation__item--parent" data-label="Study">
Study
<ul class="uol-header-local-navigation__sub-nav" data-title="Study">
<li class="uol-header-local-navigation__item ">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/undergraduate">
Undergraduate
</a>
</li>
<li class="uol-header-local-navigation__item ">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/masters">
Masters courses
</a>
</li>
<li class="uol-header-local-navigation__item ">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/research">
Research degrees
</a>
</li>
<li class="uol-header-local-navigation__item ">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/international-students">
International students
</a>
</li>
<li class="uol-header-local-navigation__item ">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/online-courses">
Online courses
</a>
</li>
<li class="uol-header-local-navigation__item uol-header-local-navigation__item--cta">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/courses-search">
Search courses
</a>
</li>
<li class="uol-header-local-navigation__item uol-header-local-navigation__item--cta">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/coronavirus-faqs">
Coronavirus FAQs
</a>
</li>
<li class="uol-header-local-navigation__item uol-header-local-navigation__item--cta">
<a class="uol-header-local-navigation__link uol-header-local-navigation__link--sub-nav" href="/study/ug-virtual-open-days">
Undergraduate virtual open days
</a>
</li>
</ul>
</li>
<li class="uol-header-local-navigation__item " data-label="Research and innovation">
<a class="uol-header-local-navigation__link" href="/research-innovation">
Research and innovation
</a>
</li>
<li class="uol-header-local-navigation__item " data-label="Working with business">
<a class="uol-header-local-navigation__link" href="/working-with-business">
Working with business
</a>
</li>
<li class="uol-header-local-navigation__item " data-label="Global">
<a class="uol-header-local-navigation__link" href="/global">
Global
</a>
</li>
<li class="uol-header-local-navigation__item " data-label="Around campus">
<a class="uol-header-local-navigation__link" href="/ariund-campus">
Around campus
</a>
</li>
<li class="uol-header-local-navigation__item " data-label="About">
<a class="uol-header-local-navigation__link" href="/about">
About
</a>
</li>
</ul>
</nav>
// Utility
.no-wrap {
white-space: nowrap;
}
@mixin local-navigation-link-accent {
&::after {
content: "";
position: absolute;
bottom: 0;
left: calc(#{$spacing-4} - 2px);
right: calc(100% - #{$spacing-4} + 2px);
height: $spacing-2;
background-color: $color-white;
transition: right 0.4s ease 0.1s;
}
&:focus {
outline: 2px dotted transparent;
}
&:hover,
&:focus {
&::after {
right: calc(#{$spacing-4} - 2px);
background-color: $color-brand;
@media (-ms-high-contrast: active),
(forced-colors: active) {
background-color: WindowText;
background-color: CanvasText;
}
}
}
}
.uol-header-local-navigation-wrapper {
max-width: 101.75rem;
.no-js & {
margin: $spacing-4 0;
padding-bottom: $spacing-4;
}
.js & {
position: relative;
padding-top: $spacing-2;
padding-bottom: $spacing-2;
margin-top: 0;
@include media(">=uol-media-l") {
margin-top: $spacing-6;
padding-left: $spacing-2;
}
@include media(">=uol-media-xl") {
padding-left: $spacing-4;
}
@include media(">=uol-media-xxl") {
padding-left: 0;
}
}
}
.uol-header-local-navigation-wrapper--scrollable {
border-top: 1px solid $color-border--light;
}
.uol-header-local-navigation-wrapper--sub-expanded {
@include media("<uol-media-m") {
padding-bottom: 0;
}
}
.uol-header-local-navigation {
.js & {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
scroll-snap-type: x proximity;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
.uol-header-local-navigation--scrollable {
.js & {
margin-left: $spacing-6;
margin-right: $spacing-6;
}
.uol-header-local-navigation-wrapper--sub-expanded & {
@include media("<uol-media-m") {
margin-left: 0;
margin-right: 0;
}
}
}
.uol-header-local-navigation__button-scroll {
position: absolute;
top: 0;
z-index: 1;
width: $spacing-7;
height: 100%;
background: rgba($color-white, 0.96);
border: none;
transition: opacity 0.3s ease;
&::after {
content: "";
display: block;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border: 7px solid transparent;
@media (-ms-high-contrast: active), (forced-colors: active) {
-ms-high-contrast-adjust: none;
forced-color-adjust: CanvasText;
}
}
&[disabled] {
// background: none;
opacity: 0;
cursor: default;
z-index: -1;
}
.uol-header-local-navigation-wrapper--sub-expanded & {
@include media("<uol-media-m") {
display: none;
}
}
}
.uol-header-local-navigation__button-scroll--left {
left: 0;
border-right: 1px solid $color-border--light;
&::after {
left: $spacing-3;
border-right-color: $color-brand--bright;
}
}
.uol-header-local-navigation__button-scroll--right {
right: 0;
border-left: 1px solid $color-border--light;
&::after {
right: $spacing-3;
border-left-color: $color-brand--bright;
}
}
.uol-header-local-navigation__item {
font-weight: $font-weight-bold--sans-serif;
@include media("<uol-media-m") {
font-weight: 500; // TODO: May need to update font weights
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.js .uol-header-local-navigation__sub-nav & {
padding: $spacing-2 $spacing-4;
}
}
.uol-header-local-navigation__item--sibling-open {
@include media("<uol-media-m") {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
width: 1px;
overflow: hidden;
left: -9999px;
}
}
.uol-header-local-navigation__item--cta {
.js & {
background: $color-black;
margin-left: -1px;
margin-right: -1px;
margin-bottom: -1px;
border: 1px solid $color-black;
@include media(">=uol-media-m") {
&:last-of-type {
border-radius: 0 0 $spacing-3 $spacing-3;
}
}
}
.js .uol-header-local-navigation__sub-nav & {
// Add extra spacing to first and last cta (assuming cta is last item)
margin-top: $spacing-4;
padding-top: $spacing-5;
padding-bottom: $spacing-2;
~ .uol-header-local-navigation__item--cta {
margin-top: 0;
padding-top: 0;
}
&:last-of-type {
padding-bottom: $spacing-6;
}
}
}
.uol-header-local-navigation__link {
.no-js & {
// padding: $spacing-1 $spacing-2 $spacing-2;
&:hover,
&:focus {
text-decoration: underline;
}
}
.js & {
@extend %text-size-paragraph;
@include local-navigation-link-accent();
position: relative;
display: block;
color: $color-font--light;
text-decoration: none;
white-space: nowrap;
padding: $spacing-2 $spacing-4 $spacing-3;
transition: color 0.4s ease 0.1s;
&:hover,
&:focus {
color: $color-font--dark;
}
&[aria-current] {
color: $color-brand;
}
}
.js .uol-header-local-navigation__sub-nav & {
background: $color-white;
color: $color-font--light;
white-space: normal;
transition: background 0.5s ease;
border-radius: 6px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
&:hover,
&:focus {
background-color: $colour-warmgrey—faded;
color: $color-font;
text-decoration: underline;
}
&[aria-current] {
color: $color-brand;
}
&::after {
content: none;
}
svg {
position: relative;
top: 0.35em;
left: 0;
margin-left: 0.5em;
fill: rgba($color-brand, 0);
transition: all 0.3s ease 0.2s;
}
&:hover,
&:focus {
svg {
left: 0.4em;
fill: $color-brand;
@media (-ms-high-contrast: active) {
fill: windowText;
}
}
}
}
.js .uol-header-local-navigation__item--cta & {
background: inherit;
color: $color-white;
padding-top: $spacing-1;
padding-bottom: $spacing-1;
@include media(">=uol-media-m") {
font-size: 18px;
}
&:hover,
&:focus {
background-color: $color-black--dark;
color: $color-white;
}
&[aria-current] {
color: $color-brand--bright;
}
svg {
fill: $color-brand--bright;
@media (-ms-high-contrast: active) {
fill: windowText;
}
}
&:hover,
&:focus {
svg {
left: 0.4em;
fill: $color-brand--bright;
@media (-ms-high-contrast: active) {
fill: windowText;
}
}
}
}
}
.uol-header-local-navigation__subnav-button {
@extend %text-size-paragraph;
@include local-navigation-link-accent();
position: relative;
font-weight: inherit;
white-space: nowrap;
background: transparent;
border: none;
margin: 0;
padding: $spacing-2 $spacing-4 $spacing-3;
appearance: none;
color: $color-font--light;
transition: color 0.4s ease 0.1s;
&[aria-expanded="true"] {
@include media("<=uol-media-m") {
&:focus {
text-decoration: underline;
}
&:focus:not(:focus-visible) {
text-decoration: none;
}
&:focus-visible {
outline-color: transparent;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: $spacing-2;
text-decoration-color: $color-brand--bright;
}
}
}
&:focus {
outline-offset: -4px;
}
&:hover,
&:focus {
color: $color-font--dark;
}
&[aria-expanded="true"] {
color: $color-font--dark;
@include media(">=uol-media-m") {
&::before {
content: "";
position: absolute;
right: 0;
transform: translateX(-70%);
bottom: ($spacing-2 - $spacing-1 / 2);
width: 0;
height: 0;
border: ($spacing-3 - $spacing-1 / 2) solid transparent;
border-top: none;
border-bottom-color: $color-white;
filter: drop-shadow(0 -0.05rem 0.05rem rgba($color-black, 0.1));
z-index: 4;
}
}
}
// TODO: Un-nest icon
.uol-header-local-navigation__button__icon {
position: relative;
display: inline-block;
width: $spacing-5;
height: $spacing-4;
margin-left: 0.2em;
margin-right: -0.2em;
&::before,
&::after {
content: "";
display: block;
position: absolute;
width: 0.5em;
height: 0.13em;
background: $color-black;
bottom: 20%;
@media (-ms-high-contrast: active) {
background: ButtonText;
}
}
&::before {
left: 50%;
transform: translateX(-76%) rotate(45deg);
}
&::after {
right: 50%;
transform: translateX(76%) rotate(-45deg);
}
}
// TODO: Duplicate selector - refactor
&[aria-expanded="true"] {
@include media("<uol-media-m") {
@include font-size-responsive(1.75rem, 2.25rem, 3rem);
@include line-height-responsive(2.25rem, 3rem, 3.5rem);
display: block;
text-align: left;
width: 100vw;
border-bottom: 2px solid $color-border--light;
@include media("<uol-media-m") {
margin-top: -#{$spacing-2};
padding: 1.312rem $spacing-7 1.312rem $spacing-4;
}
&::after {
content: none;
}
@include media(">=uol-media-m") {
&::before {
content: "";
width: 30px;
height: 30px;
background: red;
position: absolute;
}
}
}
// TODO: Un-nest icon
.uol-header-local-navigation__button__icon {
&::before {
transform: translateX(-76%) rotate(315deg);
}
&::after {
transform: translateX(76%) rotate(45deg);
}
@include media("<uol-media-m") {
position: absolute;
padding: $spacing-4;
right: $spacing-3;
top: 50%;
transform: translateY(-50%);
&::before {
bottom: 50%;
}
&::after {
bottom: 50%;
}
}
}
}
}
.uol-header-local-navigation__sub-nav {
.js & {
padding: 0;
list-style: none;
display: none;
box-shadow:
0 15px 24px 0 rgba(10, 2, 2, 0.15),
0 5px 10px 0 rgba(33, 33, 33, 0.5),
0 5px 15px 2px rgba(255, 255, 255, 0.25);
@include media("<uol-media-m") {
padding-top: $spacing-4;
background: $color-white;
width: 100vw;
overflow-y: auto;
overflow: hidden;
@media (-ms-high-contrast: active) {
border-bottom: 1px solid windowText;
}
}
@include media(">=uol-media-m") {
position: absolute;
top: calc(100% - #{$spacing-4});
box-sizing: border-box;
width: 375px;
background: $color-white;
border: 1px solid rgba($color-border--light, 0.2);
border-radius: $spacing-3;
padding-top: $spacing-1;
z-index: 1001;
transform: translateX(-#{$spacing-4});
}
}
}
const localNavigations = document.querySelectorAll('.uol-header-local-navigation')
const svgRightArrow = `<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" focusable="false" aria-hidden="true">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"/>
</svg>`
// TODO: Move to utilities
const getSiblings = (elem) => {
return Array.prototype.filter.call(elem.parentNode.children, (sibling) => {
return sibling !== elem
})
}
const closestByClass = (elem, classSelector) => {
// Traverse the DOM up with a while loop
while (elem.className != classSelector) {
// Increment the loop to the parent node
elem = elem.parentNode
if (!elem) {
return null
}
}
return elem
}
export const localNavigationDropdown = () => {
const subNavOpen = (navigation, navBtn, subNav, siblings) => {
navBtn.setAttribute('aria-expanded', 'true')
subNav.style.display = 'block'
// Toggle the siblings
siblings.forEach((sibling) => {
sibling.classList.add('uol-header-local-navigation__item--sibling-open')
})
navigation.classList.add('uol-header-local-navigation--sub-expanded')
navigation.parentNode.classList.add('uol-header-local-navigation-wrapper--sub-expanded')
}
const subNavClose = (navigation, navBtn, subNav, siblings) => {
subNav.style.display = 'none'
navBtn.setAttribute('aria-expanded', 'false')
// Toggle the siblings
siblings.forEach((sibling) => {
sibling.classList.remove('uol-header-local-navigation__item--sibling-open')
})
navigation.classList.remove('uol-header-local-navigation--sub-expanded')
navigation.parentNode.classList.remove('uol-header-local-navigation-wrapper--sub-expanded')
navigation.dispatchEvent(new CustomEvent('scroll'))
}
localNavigations.forEach( (navigation) => {
const navItems = navigation.querySelectorAll('.uol-header-local-navigation__item')
navItems.forEach( (navItem) => {
// Scroll items fully into view (exclude sub nav)
if (!navItem.parentNode.classList.contains('uol-header-local-navigation__sub-nav')) {
const navLink = navItem.querySelector('.uol-header-local-navigation__link')
navLink.addEventListener('focus', () => {
navItem.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start'
})
})
}
const subNav = navItem.querySelector('.uol-header-local-navigation__sub-nav')
if (subNav) {
const siblings = getSiblings(navItem)
const navLabel = navItem.dataset.label
const subNavItems = subNav.querySelectorAll('.uol-header-local-navigation__item')
// Hide subNav
subNav.style.display = 'none'
// Remove text nodes
navItem.childNodes.forEach( childNode => {
if (childNode.nodeName === '#text') {
childNode.remove()
}
})
// TODO Add support for top level links
// Add button
let navBtn = document.createElement('button')
navBtn.type = 'button'
navBtn.classList.add('uol-header-local-navigation__subnav-button')
navBtn.innerHTML = navLabel + '<span class="uol-header-local-navigation__button__icon"></span>'
navBtn.setAttribute('aria-expanded', false)
navItem.prepend(navBtn)
navBtn.onclick = () => {
let expanded = navBtn.getAttribute('aria-expanded') === 'true' || false
if (!expanded) {
subNavOpen(navigation, navBtn, subNav, siblings)
} else {
subNavClose(navigation, navBtn, subNav, siblings)
}
}
// Listen for focusout and close subnav when focus leaves the item's descendants
navItem.addEventListener('focusout', (event) => {
if (event.relatedTarget) {
// If the new focused element is not a child of a sub nav
if (!closestByClass(event.relatedTarget, 'uol-header-local-navigation__sub-nav')) {
// if not this navigation item's toggle button
if(event.relatedTarget.parentNode != navItem) {
subNavClose(navigation, navBtn, subNav, siblings)
}
}
}
})
// Close on click outside
document.addEventListener("click", (evt) => {
let targetElement = evt.target; // clicked element
do {
if (targetElement == navItem) {
// This is a click inside. Do nothing, just return.
return;
}
// Go up the DOM
targetElement = targetElement.parentNode;
} while (targetElement)
// This is a click outside.
subNavClose(navigation, navBtn, subNav, siblings)
})
// Close on escape
window.addEventListener("keydown", function(event) {
if (event.key === 'Escape' || event.keyCode === 27) {
subNavClose(navigation, navBtn, subNav, siblings)
// If focus is on a subnav return focus to parent toggle button
if (event.target.classList.contains('uol-header-local-navigation__link--sub-nav')) {
const parentButton = event.target.closest('.uol-header-local-navigation__item--parent').querySelector('.uol-header-local-navigation__subnav-button')
if (parentButton) {
parentButton.focus()
}
}
}
}, true);
// Add arrows to subnav links
subNavItems.forEach( (item) => {
const itemLink = item.querySelector('.uol-header-local-navigation__link')
// Split text to array
const innerTextArray = itemLink.innerText.trim().split(' ')
// Wrap last word and svg in no-wrap span to avoid wrapping
itemLink.innerHTML = innerTextArray.slice(0, -1).join(' ') + ' <span class="no-wrap">' + innerTextArray[innerTextArray.length - 1] + '' + svgRightArrow + '</span>'
})
}
})
})
}
export const localNavigationScrollButtons = () => {
const createScrollableNav = (navigation) => {
const viewportWidthScroll = window.innerWidth * 0.5
if (!navigation.classList.contains('uol-header-local-navigation--scrollable')) {
const navParent = navigation.parentNode
// Add class to navigation for JS dependant spacing
navigation.classList.add('uol-header-local-navigation--scrollable')
navigation.parentNode.classList.add('uol-header-local-navigation-wrapper--scrollable')
// Create left scroll button
const btnLeft = document.createElement('button')
btnLeft.classList.add('uol-header-local-navigation__button-scroll')
btnLeft.classList.add('uol-header-local-navigation__button-scroll--left')
btnLeft.disabled = true
btnLeft.innerHTML = '<span class="hide-accessible">Scroll navigation left</span>'
btnLeft.onclick = () => {
navigation.scrollBy({
left: -viewportWidthScroll,
behavior: 'smooth'
})
}
// Create Right scroll button
const btnRight = document.createElement('button')
btnRight.classList.add('uol-header-local-navigation__button-scroll')
btnRight.classList.add('uol-header-local-navigation__button-scroll--right')
btnRight.innerHTML = '<span class="hide-accessible">Scroll navigation right</span>'
btnRight.onclick = () => {
navigation.scrollBy({
left: viewportWidthScroll,
behavior: 'smooth'
})
}
// Prepend/Append scroll buttons
navParent.prepend(btnLeft)
navParent.append(btnRight)
// listen for scrolling end and update scroll buttons disabled state
let navIsScrolling
navigation.addEventListener('scroll', () => {
window.clearTimeout( navIsScrolling )
navIsScrolling = setTimeout(() => {
// The following have a 5px tolerance to support browsers that do not support scroll snapping
// If very near the beginning of scroll
if (navigation.scrollLeft <= 5) {
btnLeft.disabled = true
} else {
btnLeft.disabled = false
}
// If very near the end of scroll
if ((navigation.scrollLeft + navigation.clientWidth) - navigation.scrollWidth >= -5 ) {
btnRight.disabled = true
} else {
btnRight.disabled = false
}
}, 66)
}, false)
}
}
const destroyScrollableNav = (navigation) => {
// Remove class to navigation for JS dependant spacing
navigation.classList.remove('uol-header-local-navigation--scrollable')
navigation.parentNode.classList.remove('uol-header-local-navigation-wrapper--scrollable')
document.querySelectorAll('.uol-header-local-navigation__button-scroll').forEach( (button) => {
button.remove()
})
}
const initiateScrollableNav = () => {
localNavigations.forEach((navigation) => {
if (navigation.scrollWidth - 10 > navigation.clientWidth) { // TODO fix ipad landscape showing scroller
createScrollableNav(navigation)
} else {
destroyScrollableNav(navigation)
}
})
}
// Initialise
document.addEventListener('DOMContentLoaded', function() {
initiateScrollableNav()
});
// Fire again on resize
window.addEventListener('resize', initiateScrollableNav)
// TODO: Hack fix of nav that is just too wide while webfonts load. Need a better solution
setTimeout(() => {
if (typeof(Event) === 'function') {
// modern browsers
window.dispatchEvent(new Event('resize'));
} else {
// for IE and other old browsers
// causes deprecation warning on modern browsers
var evt = window.document.createEvent('UIEvents');
evt.initUIEvent('resize', true, false, window, 0);
window.dispatchEvent(evt);
}
}, 300)
}
{
"items": [
{
"title": "Home",
"url": "/",
"current": true
},
{
"title": "Study",
"items": [
{
"title": "Undergraduate",
"url": "/study/undergraduate"
},
{
"title": "Masters courses",
"url": "/study/masters"
},
{
"title": "Research degrees",
"url": "/study/research"
},
{
"title": "International students",
"url": "/study/international-students"
},
{
"title": "Online courses",
"url": "/study/online-courses"
},
{
"cta": true,
"title": "Search courses",
"url": "/study/courses-search"
},
{
"cta": true,
"title": "Coronavirus FAQs",
"url": "/study/coronavirus-faqs"
},
{
"cta": true,
"title": "Undergraduate virtual open days",
"url": "/study/ug-virtual-open-days"
}
]
},
{
"title": "Research and innovation",
"url": "/research-innovation"
},
{
"title": "Working with business",
"url": "/working-with-business"
},
{
"title": "Global",
"url": "/global"
},
{
"title": "Around campus",
"url": "/ariund-campus"
},
{
"title": "About",
"url": "/about"
}
]
}