DEV Community

Cover image for Make anchors in links work in EmberJS
Michal Bryxí
Michal Bryxí

Posted on • Updated on


Make anchors in links work in EmberJS

Every web app starts with an URL. And commonly used URLs for web apps usually look something like:
Enter fullscreen mode Exit fullscreen mode

The last bit (fragment) can be used to instruct the browser to scroll the page to the element that has the same id as said fragment. Those are usually called anchors or in-page-anchors. Example:

<!-- <a> element links to the section below -->
<p><a href="#Section_further_down">
  Jump to the heading below

<!-- Heading to link to -->
<h2 id="Section_further_down">Section further down</h2>
Enter fullscreen mode Exit fullscreen mode

The scrolling works when the user clicks on a link on current page and also when the user opens the URL from bookmarks or other app.

The problem

Unfortunately with the advent of Single-page applications (SPAs), this nifty feature of the browsers stopped working.

Why? Because initially, SPA has minimal HTML with a link to a big JavaScript bundle that will eventually get parsed by the browser and the JS code will populate the DOM with respective elements based on URL, data, code logic, etc.

So at the initial page load when the browser checks in the DOM for the presence of an tag that has the same id as the fragment in the URL it will find nothing because the DOM is almost empty.

The solution

Luckily EmberJS has an addon (ember-url-hash-polyfill) that solves exactly this kind of problem in a very elegant way. From the addon README:

Navigating to URLs with #hash-targets in them is not supported by most single-page-app frameworks due to the async rendering nature of modern web apps -- the browser can't scroll to a #hash-target on page load/transition because the element hasn't been rendered yet.

This addon provides a way to support the behaviour that is normally native to browsers where an anchor tag with href="#some-id-or-name" would scroll down the page when clicked.

Once you install it:

ember install ember-url-hash-polyfill
Enter fullscreen mode Exit fullscreen mode

You just have to adjust your app router.js and add a withHashSupport decorator:

// app/router.js

import { withHashSupport } from 'ember-url-hash-polyfill';

export default class Router extends EmberRouter {
  location = config.locationType;
  rootURL = config.rootURL;
Enter fullscreen mode Exit fullscreen mode

And after that all URLs with in-page-anchors in them should just work™.

Photo by Lucas Sankey on Unsplash

Top comments (0)