The software teams I have worked with over the last 10 years have primarily developed single-page applications (SPA). Last year, I published the article Warning signs of front-end complexity as a way to reflect on the problems encountered with this approach and to provide a way forward. Since then, I directed two software teams on migrating their single-page architecture to a multi-page architecture.
When relying on client-side routing for so long, it can be easy to forget how else to do it. As such, developers have asked me during these architecture migrations:
Should this be a link or a button?
My most effective response is simply:
Use links when user input is not needed, such as for a website’s navigation.
If a page links to itself, it may include extra data in its query string to support dynamic server-side rendering. For example,
sort keys could provide basic pagination functionality.
Links can also be used to apply settings for a page. Like pagination, changing the sort order uses the
The server inspects the current
sort value in the URL and dynamically applies it to all the pagination links.
Use in-page links with
# in the
href value to navigate to specific content on the same page. This is commonly used for:
- table of contents for pages with many distinct sections
- skip links at the top of the page for keyboard users
- back-to-top link (
#top) at the bottom of a long page
Use submit buttons with forms when user input is needed. The
value attributes on form fields are sent to the server on submit.
Use a form’s
get method to change the view of a page based on user input, such as displaying a list of items sorted in a user-specified way. In this particular case, the result is effectively identical to the previously described link-based solution.
Use a form’s
post method to create, update, or delete resources. Hidden input fields can indicate the particular action to take on the given resource (Option 1). Alternatively, the hidden input fields could be replaced by a convention that includes the action and resource identifier in the form’s
action URL (Option 2).
Buttons do not submit a form when they are:
- outside a form
- within a form with the
How links or buttons should be used primarily depends on the need for user input and the intended default browser behavior.
- Prevent a form from submitting in order to provide custom client-side validation.
- Use a button instead of making another element (like a
div) behave as a button.
Overall, it is more reliable and maintainable to align as much as possible with default browser behavior. Use native HTML elements in the way they were intended. This saves development time and circumvents incidental usability and accessibility issues.