Can hash routes be defined in next.js?

Previously, I created a modal component using <HashRouter> in react-router where the modal would become active or inactive based on the hash url. For example, the modal is inactive when the url is /route, but becomes active when the url is /route#modal1. Is there any method to define hash routes in next.js?

Answer №1

When dealing with URLs, it's important to note that the hash symbol portion (which identifies an HTML entity) is not transmitted to the server. This means that you won't be able to match the URL serverside if a browser loads something like /route#modal1 - the server will only see /route. However, there are ways to work around this:

Option 1: Manage modal rendering on the client side using next/router in your component. Here's a sample code snippet assuming you're working with class components:

import Router from 'next/router'

....

componentDidMount(){
  let id = Router.asPath.match(/#([a-z0-9]+)/gi )
  if(id){
    // show the modal
  }else{
    // do something else
  }
}

Option 2: Pass the ID to the URL without the #. In your server.js, add a route similar to the following:

server.get('/route/:id?', (req, res) => {
  let {id} = req.params 
  return app.render(req, res, '/mypage', { id })
})

Then extract the ID, for example in getInitialProps:

static async getInitialProps (context) {
  let ctx  = context.query;
  return ctx
}

You can then handle the modal accordingly:

componentDidMount(){
  let {id} = this.props    
  if(id){
    // show the modal
  }else{
    // do something else
  }
}

Answer №2

If you want to achieve this functionality, you can utilize the next/router.

For example, we implement hash routing on a specific page to display different components based on the hash URL. This allows users to navigate back and forth using standard web navigation buttons.

// page.js

export default function MyPage() {
  const router = useRouter();
  const hash = router.asPath.split('#')[1] || '';
  const showModal = hash === 'modal1' ? true : false;
  const openModal = () => {
    router.push({ hash: 'modal1' });
  }  
  return (
    <>
      <h1>MyPage</h1>
      <Button onClick={openModal}>Open Modal 🙂</Button>
      {showModal && <ModalOne />}
    </>
  )
}
// ModalOne.js

export default function ModelOne {
  const router = useRouter();
  const closeModal = () => {
    router.push({ hash: '' });
  }
  return (
    <>
        <h1>Hello Modal</h1>
        <Button onClick={closeModal}>Close Modal 🙃</Button>
    </>
  )
}

Whenever the router hash changes, a re-render occurs, allowing the modal to open similarly to how it would in a single-page application.

This setup also ensures that the modal closes when the user navigates back on a mobile device, aligning with our expected behavior for this scenario.

Please note that I am working with nextjs version 12.1.0

Answer №3

To include a hash in the URL, you can utilize the next/router library.

In certain scenarios, I dynamically alter the component being rendered based on a state string. To ensure that I am aware of the current route and maintain functionality of the back button, I append a state string stage as a hash to the URL when a change is detected.

React.useEffect(() => {
  router.push(`/booking#${stage}`)
}, [stage])

Please note that this approach is specifically for client-side operations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for using conditional rendering with React and TypeScript

Issue with Conditional Rendering in TypeScript It seems like I might have encountered a problem with the way I declare my components. Take a look at this TypeScript snippet: import React, { FunctionComponent } from 'react'; export const Chapte ...

Having difficulty displaying form errors using handlebars

My form validation is not working properly. When I enter incorrect information, it alerts correctly, but when I submit the form, it returns [Object object]. What could be causing this issue in my code and how should I handle the data? https://i.stack.imgu ...

Generate a fresh collection of objects all sharing a common identifier within a given array

Looking for help transforming this schedules array to match the desired output. Any ideas? let schedules = [ {day: 'Sunday', time: '5:00 PM'}, {day: 'Monday', time: '4:00 PM'}, {day: 'Monday', time: &ap ...

Managing the onChange event for a MaterialUI dropdown component

I'm encountering an issue with validating the MaterialUI TextField component (Country list) wrapped with Autocomplete. I am trying to use the onChange event to enable the Submit button when the country field is filled in. However, the problem arises w ...

Obtain the dynamic identifier of an element within every block using jQuery in a rails application

Let me illustrate my issue with a simple example. I am currently developing a recipe application. Within the show partial that loads via AJAX, I have the following setup: _show.html.erb <% @recipe.ingredients.each do |ingredient| %> <div class ...

yii2: Utilizing the power of dynamic calling in widgets

Imagine I have a widget called Widget1; In the view file, I call this widget like so: <?= Widget1::widget() ?> Clicking on an element should trigger a new instance of the widget and execute its JavaScript scripts. However, I am unable to get the s ...

When utilizing the data property within the useQuery() hook, an error may arise stating "Unable to

This problem has me scratching my head. The code snippet below is triggering this error: TypeError: Cannot read properties of undefined (reading 'map') When I use console.log() to check res.data, everything seems normal and there is data present ...

Can I use more than one AudioContext at a time?

In my project, I am developing a React App using MeteorJS that utilizes the Web Audio API. This app consists of multiple pages, each of which utilizes web audio functionality. The issue I am facing is that I have hit the limit of 6 audio contexts allowed i ...

"Troubleshooting: Why is my AngularJS ng-repeat failing to

I recently started delving into AngularJS, but I've hit a roadblock with a particular issue. For some reason, the ng-repeat directive isn't iterating through the users array as expected. The resulting list is just blank. Below is a snippet of my ...

Is Angular automatically assigned to `window.angular` on a global level when it is loaded as a CommonJS module?

When I import Angular 1.4 in my Webpack build entry point module as a CommonJS module using var angular = require("angular");, it somehow ends up being accessible in the global namespace of the browser (as window.angular). Upon examining the source code o ...

Switching over from create-react-app to NextJS, encountering difficulties with integrating ThreeJS

A while back, I had successfully implemented a 3D model viewer in React. Now, I'm facing a challenge as I try to migrate this project to Next.js. The specific issue lies with the GLTFLoader and OrbitControls dependencies that were previously imported ...

Is Immutable state considered a key functional aspect in the ReactJs framework?

One key aspect of an imperative program is the emphasis on state and its modifications. When it comes to ReactJs, there is a push for more functional programming styles, such as using purity and higher-order functions. I'm curious to explore whether ...

No bugs appeared in Next.js

I am currently in the process of migrating a large create-react-app project to NextJS. To do this, I started a new Next project using create-next-app and am transferring all the files over manually. The main part of my page requires client-side rendering f ...

Getting rid of an Ajax loader graphic after a period of time

After a button is clicked, I have an ajax loader that appears and here is the code snippet: jQuery(document).ready(function($) { $('#form').on('submit', function() { $('#submit').css('display', 'bl ...

Can the contents of a JSON file be uploaded using a file upload feature in Angular 6 and read without the need to communicate with an API?

Looking to upload a JSON file via file upload in Angular (using version 6) and read its contents directly within the app, without sending it to an API first. Have been searching for ways to achieve this without success, as most results are geared towards ...

"Once the initial date has been selected, v-Calendar's datepicker allows for setting a

Is there a way to trigger an event for the date range picker of v-calendar after the first date is picked or prevent the inputs from adding the dates until both dates have been selected? Here is the Vue component I have: new Vue({ el: "#app", data( ...

Understanding Mongodb: the process of populating a schema that is referenced within another schema using an API

Looking to make adjustments to my Api in order to populate a referenced schema. Here's the schema I am working with: export const taskSchema = new Schema ({ user:{ type: String, required: true }, project: { type ...

How to effectively utilize signed requests for AWS S3 when uploading images?

My project involves developing a react native application similar to Slack, and I'm currently facing an issue with image uploads to S3. I decided to use the getSignedUrl route for this functionality. The process goes as follows: the client selects a ...

Extracting information from HTML and transferring it to Javascript using jQuery

My goal is to utilize jsGrid for showcasing database data without repeating code extensively. I aim to generate separate grids for each <div> with a specific id while passing on relevant values accordingly. To clarify my objective, here's a sni ...

Adjust the size of the font in your Bootstrap Table

I've been utilizing the Bootstrap table feature and it's been fantastic, but I've encountered an issue with changing the font size. I've referred to the example on , however no matter what adjustments I make to the size, it doesn' ...