简体   繁体   中英

NextJS use getServerSideProps with a specific URL path

I've been using the solution at NextJS deploy to a specific URL path (and Deploy your NextJS Application on a different base path (ie not root) ) for a year now on our project. Our next.js server is hosted on another website under a sub-path, but the sub-path comes from the other server, not ours. Ie we're at http://example.com/project/path . But our server is running at http://localhost:8081/ so we can't use the basePath since that changes our local path. This has been working great. We use a wrapped next/link for our links and just prepend our own basePath to API calls in most cases.

I recently tried switching to use getServerSideProps() rather than getInitialProps() since I was reading online that is the new preferred way (a single API call rather than the multiple we were making before). The problem I'm having is that I can't find a way to tell next.js that it needs to add the basePath to the getServerSideProps API calls it makes. We are using assetPrefix to point our images and css at the sub-path but it looks like there was a bug https://github.com/vercel/next.js/issues/15563 which was fixed that let us use assetPrefix rather than basePath.

Again, we can't use basePath since it changes localhost to http://localhost/project/path and it's the external website that has the extra pathing. Is there any other solution? Or are we just stuck on getIntialProps since it works and hope we don't lose that option in the future?

Currently, server-side rendering works, but when I navigate client-side, it returns a 404 on the getServerSideProps API call and the browser than redirects and loads the page server-side like: Chrome network load . While it "works", it's not very performant since it must server-side render every page.

Edit: The proposed solution https://stackoverflow.com/a/66642225/1870780 does not work since we cannot use a basePath since it changes the local server base, not a remote server path pointing to our server.

Thank you @juliomalves for pointing me in the direction of the solution. The discussion at https://github.com/vercel/next.js/discussions/25681#discussioncomment-2026813 has a potential solution which works. In-lining the solution here to save others time, but credit goes to alizeait for the solution. Main difference between my solution an his, is his namespace does not include a leading / while mine does.

Typescript solution:

import { AppProps } from "next/app";
import { Router } from "next/router";
import { useEffect } from "react";

const useInterceptNextDataHref = ({
  router,
  namespace
}: {
  router: Router;
  namespace: string;
}) => {
  useEffect(() => {
    if (router.pageLoader?.getDataHref) {
      const originalGetDataHref = router.pageLoader.getDataHref;
      router.pageLoader.getDataHref = function (args: {
        href: string;
        asPath: string;
        ssg?: boolean;
        rsc?: boolean;
        locale?: string | false;
      }) {
        const r = originalGetDataHref.call(router.pageLoader, args);
        return r && r.startsWith("/_next/data")
          ? `${namespace}${r}`
          : r;
      };
    }
  }, [router, namespace]);
};

export default function MyApp ({ Component, pageProps, router }: AppProps) {
  useInterceptNextDataHref({
    router,
    namespace: "/my-base-path"
  });
  return <Component {...pageProps} />;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM