gdfgdfg
gdfgdfg

Reputation: 3566

Pass data (prop) from _app.js to getServerSideProps in a page - NextJS, latest version

I have a custom _app.js:

  const Layout = ({ children }) => (children);

  const app = ({ Component, pageProps }) => {

    pageProps.baseUrl = 'some url';

    return (
      <Layout>
        <Component {...pageProps} />
      </Layout>
    )
};

And a page:

export async function getServerSideProps({ req, query, res, baseUrl }) { 
// baseUrl is undefined and an error, if I am using it with destructiring

  console.log(req) // There is no baseUrl

  return { props: { ..... } }
}

I want to set that pageProps.baseUrl= 'some url'; in _app.js and use it in page components including getServerSideProps, how can I do that ?

Upvotes: 4

Views: 8174

Answers (2)

gdfgdfg
gdfgdfg

Reputation: 3566

For now, I have created a file, which contains all global values like this:

let store = {};

const globalStore = {};

globalStore.set = (key, value) => {
    store = { ...store, [key]: value };
}

globalStore.get = (key) => {
    return store[key];
}


export default globalStore;

Then in _app.js import it and set a value:

const app = ({ Component, pageProps }) => {
    globalStore.set('baseUrl', 'some url 1');
    globalStore.set('baseUrl2', 'some url 2');

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

import the file in pages/index.js and inside the component or getServerSideProps:

export async function getServerSideProps({ req, query, res }) {

    console.log('in getServerSideProps');
    console.log(globalStore.get('baseUrl'));
    console.log(globalStore.get('baseUrl2'));
...

Upvotes: 3

bmdev
bmdev

Reputation: 426

I think, in this particular case, it's ok to use constants here instead of props.

Proposed solution

In constants.js:

export const BASE_URL = 'some url';

And in your page:

import * as Constants from '../path/to/constants';

export async function getServerSideProps({ req, query, res }) { 
  // use Constants.BASE_URL here

  return { props: { ..... } }
}

Why won't props work the way you want them to?

Your page component and the getServerSideProps method you export from the file are separate, and are executed at different times. Rendering your component does not call getServerSideProps. I believe the order in Next.js is like this:

  1. A request is made at a route.
  2. Next.js looks at the file in pages/ for the corresponding route
  3. Next.js will run the appropriate method based on the execution context (on a server render, getServerSideProps)
  4. Next.js renders the App component, passing it the pageProps provided from getServerSideProps
  5. The App component renders the Page component

In this case, you have created a paradox. Think about how the props flow:

  1. getServerSideProps runs, returns a pageProps object
  2. App component renders, containing the pageProps object passed from getServerSideProps
  3. Page component renders, passed the pageProps

If getServerSideProps is responsible for creating the pageProps object, it can't also be passed that object as an argument.

Upvotes: 1

Related Questions