1

I have 3 components in nextjs and i want to achieve the below snippet in nextjs

<Route path="/" component={homePage} />
<Route path="/about" component={aboutPage} />
<Route path="/faq" component={faqPage} />

Q1. How can i do the same in nextjs without page refresh? (without react-router)

(Edit : some scholars are suggesting to read the docs but i have read it thoroughly and what i want is to pass a component along with the route) Is this even possible in next js?

Q2: If i have url as /products?product_id=productid and on refresh if i want the url to be /products (basically i want to remove all params on refresh) What is the best practice to do this?

Thanks in advance

Akash Pai
  • 21
  • 5
  • 1
    [Next.js has a file-system based router.](https://nextjs.org/docs/routing/introduction) To prevent reload on redirection, you should use the [`next/link`](https://nextjs.org/docs/api-reference/next/link) component which enables client side transitions. For the second question you can do something like this: https://stackoverflow.com/a/65611918/11613622 – brc-dd Aug 07 '21 at 17:54
  • 2
    I’m voting to close this question because the first part is clearly covered by the docs mentioned in the comments above, and the second part is covered by the linked question. If you face any specific issues later, please ask another question. – brc-dd Aug 07 '21 at 17:58
  • @brc-dd im asking an alternative. Not about redirection. In react-router u can notice that u ll be able to send a component itself unlike where there is a transition between pages and i want to hit apis separately in both pages – Akash Pai Aug 07 '21 at 18:01
  • @brc-dd i have thoroughly read the docs and component doesnt serve my purpose. – Akash Pai Aug 07 '21 at 18:02
  • @AkashPai In Next.js you need to export that component from a page. Let's take the example of your second route: To do that in Next.js you have to create a file `pages/about.js` then define or import your `aboutPage` component there and finally `export default aboutPage`. – brc-dd Aug 07 '21 at 18:08
  • @brc-dd What's being asked is a literal replacement alternative of the component and this is not covered in the docs. Since Next.js uses it's own routing, is no longer valid as it can only be used in the traditional router. – Casey Gibson Dec 29 '21 at 23:24
  • @KcGibson Yeah I saw your answer. If the OP is asking about layouts, that's also covered in the docs, though at a different link: https://nextjs.org/docs/basic-features/layouts. Also, I never said that `` is valid. I just said that Next.js has filesystem-based routing which one needs to use. From what the OP has shown in the question, it is unclear whether they are referring to layouts. If I consider their shown code as standalone, it simply means that they can create three files corresponding to each route, and Next.js will pick them up perfectly. – brc-dd Dec 30 '21 at 06:12

3 Answers3

1

NextJS functions on a convention-based filesystem-based routing. You'd need to place your components in a directory structure that matches the routes you are wanting.

More details here:

https://nextjs.org/docs/routing/introduction

dreadwail
  • 15,098
  • 21
  • 65
  • 96
1

The Next.js docs don't really cover how to change away from <Route> components, however they have a lot of examples as code on how to do most things with Next.js. https://github.com/vercel/next.js/tree/canary/examples/layout-component

The below is what I used as an alternative to the component (there's no direct Next.js alternative).

_app.js

export default function MyApp({ Component, pageProps }) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout || ((page) => page)

  return getLayout(<Component {...pageProps} />)
}

Any page:

import Layout from '../components/layout'
import Sidebar from '../components/sidebar'

export default function About() {
  return (
    <section>
      <h2>Layout Example (About)</h2>
      <p>
        This example adds a property <code>getLayout</code> to your page,
        allowing you to return a React component for the layout. This allows you
        to define the layout on a per-page basis. Since we're returning a
        function, we can have complex nested layouts if desired.
      </p>
      <p>
        When navigating between pages, we want to persist page state (input
        values, scroll position, etc) for a Single-Page Application (SPA)
        experience.
      </p>
      <p>
        This layout pattern will allow for state persistence because the React
        component tree is persisted between page transitions. To preserve state,
        we need to prevent the React component tree from being discarded between
        page transitions.
      </p>
      <h3>Try It Out</h3>
      <p>
        To visualize this, try tying in the search input in the{' '}
        <code>Sidebar</code> and then changing routes. You'll notice the input
        state is persisted.
      </p>
    </section>
  )
}

About.getLayout = function getLayout(page) {
  return (
    <Layout>
      <Sidebar />
      {page}
    </Layout>
  )
}

The main part for the layout that you want to wrap around the pages, components/layout.js:

import Head from 'next/head'
import styles from './layout.module.css'

export default function Layout({ children }) {
  return (
    <>
      <Head>
        <title>Layouts Example</title>
      </Head>
      <main className={styles.main}>{children}</main>
    </>
  )
}

What's happening is the _app.js wraps all pages inside the declared layout. Each page then defines what layout that page belongs to. The layout then accepts a page as the {children} prop object of which you can then render anywhere in your layout page.

Casey Gibson
  • 2,577
  • 1
  • 20
  • 23
0

Next uses filesystem based routing, your folder structure should look like

-- pages 
  -- index.js
  -- about/index.js
  -- faq/index.js

For the custom component part, make a component that's clickable, on click, use next builtin router to redirect

const router = useRouter();
router.push('/');
Ahmed I. Elsayed
  • 2,013
  • 2
  • 17
  • 30