Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom property and extend DocumentInitialProps type in _document?

I'm a beginner in Typescript. I'm working on a Next.js TypeScript project. Basically, what I'm trying to do is to pass a userCurrency value from the server side, to the client via body tag. I'm working on the _document.tsx file. The issue is that I'm getting this error

enter image description here

What I gather from the error message is that userCurrency does not exist on DocumentInitialProps, and referring to other Stack Overflow posts I'm trying to extend/add an additional property userCurrency to the DocumentInitialProps.

As you can see, I created the NewDocumentInitialProps. However, the error is still there. What am I doing wrong? How do I add a custom property to DocumentInitialProps?

import { Fragment } from "react";

import Document, {
  DocumentContext,
  Html,
  Head,
  Main,
  NextScript,
  DocumentInitialProps,
} from "next/document";

declare type NewDocumentInitialProps = DocumentInitialProps & {
  userCurrency?: string;
};

export default class CustomDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<NewDocumentInitialProps> {
    const initialProps = await Document.getInitialProps(ctx);
    return {
      ...initialProps,
      ...{ userCurrency: "USD" },
    };
  }

  render(): JSX.Element {
    return (
      <Html>
        <Head>
          {
            <>
              <link rel="icon" href="/favicon_dev.svg" type="image/svg+xml" />
            </>
          }
        </Head>
        <body data-currency={this.props.userCurrency}>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
like image 392
anoop chandran Avatar asked Nov 15 '25 14:11

anoop chandran


1 Answers

Simply typing the return type of getInitialProps isn't enough to properly type this.props in the render function. You need to pass NewDocumentInitialProps as a generics to the extended Document type instead, when declaring your class.

type NewDocumentInitialProps = DocumentInitialProps & {
    userCurrency?: string;
};

export default class CustomDocument extends Document<NewDocumentInitialProps> {
    //...
}

This will also properly type getInitialProps's return type too, so you don't have to explicitly do it yourself.

like image 128
juliomalves Avatar answered Nov 18 '25 11:11

juliomalves



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!