platforms icon indicating copy to clipboard operation
platforms copied to clipboard

Production subdomains have empty props from getStaticProps

Open albertkimdev opened this issue 3 years ago • 6 comments

I added some platforms code to my app and everything was working fine until recently and now my subdomains on my production domain don't work.

Here's what my component looks like in /pages/_sites/[site]/index.js

const Index = (props) => {
  const router = useRouter();

  if (router.isFallback) {
    return <h1>Loading...</h1>;
  }
  console.log("compoennt: ");
  console.log(typeof props.site);
  console.log({ props });

  if (!props.site) return <p>error...</p>;
  const site = JSON.parse(props.site);
  if (!site.site) return <p>error...</p>;
...

On my production site I get an empty props:

image

But on localhost I get the information I expect:

image

And in my Vercel build logs, I console.log my getStaticPaths and getStaticProps and I see all the data I expect:

image

But when I visit my website like subdomain.leavewithaweb.site I see an empty props object and my site doesn't work or have the data even though it's building?

It was working like a week ago then something happened and it stopped working.

My _middleware.js

export default function middleware(req) {
  // Clone the request url
  const url = req.nextUrl.clone();

  // Get pathname of request (e.g. /blog-slug)
  const { pathname } = req.nextUrl;

  // Get hostname of request (e.g. demo.vercel.pub)
  const hostname = req.headers.get("host");
  if (!hostname)
    return new Response(null, {
      status: 400,
      statusText: "No hostname found in request headers",
    });

  const currentHost =
    process.env.NODE_ENV === "production" && process.env.VERCEL === "1"
      ? // You have to replace ".vercel.pub" with your own domain if you deploy this example under your domain.
        // You can use wildcard subdomains on .vercel.app links that are associated with your Vercel team slug
        // in this case, our team slug is "platformize", thus *.platformize.vercel.app works
        hostname.replace(`.leavewithaweb.site`, "")
      : hostname.replace(`.localhost:3000`, "");

  if (pathname.startsWith(`/_sites`))
    return new Response(null, {
      status: 404,
    });

  if (!pathname.includes(".") && !pathname.startsWith("/api")) {
    if (hostname === "localhost:3000" || hostname === "leavewithaweb.site") {
      if (
        pathname === "/" &&
        (req.cookies["next-auth.session-token"] ||
          req.cookies["__Secure-next-auth.session-token"])
      ) {
        url.pathname = `/home`;
        return NextResponse.rewrite(url);
      } else if (pathname === "/") {
        url.pathname = `/home`;
        return NextResponse.rewrite(url);
      }
    } else {
      url.pathname = `/_sites/${currentHost}${pathname}`;
      return NextResponse.rewrite(url);
    }
  }
}

My getStaticPaths and getStaticProps

export async function getStaticPaths() {
  const subdomains = await fetch(
    `${process.env.NEXT_PUBLIC_SERVER_URL}zzz`,
    {
      method: "GET",
    }
  ).then((res) => res.json());

  console.log(subdomains);

  if (subdomains.subdomains.length === 0) {
    return {
      paths: [],
      fallback: true,
    };
  } else {
    return {
      paths: subdomains.subdomains.map((subdomain) => {
        return {
          params: { site: subdomain },
        };
      }),
      fallback: "blocking",
    };
  }
}

export async function getStaticProps({ params: { site } }) {
  const siteRes = await fetch(
    `${process.env.NEXT_PUBLIC_SERVER_URL}/zzz`,
    {
      method: "GET",
    }
  ).then((res) => res.json());

  console.log(siteRes);

  return {
    props: {
      site: JSON.stringify(siteRes),
    },
    revalidate: 10,
  };
}

albertkimdev avatar May 03 '22 17:05 albertkimdev

Hey @albertkimdev! Thanks for the question. I tried accessing https://subdomain.leavewithaweb.site/ and found that you might be facing a CORS error? There's also a client side error + get static props errors based on the console logs:

CleanShot 2022-05-10 at 16 02 51

steven-tey avatar May 10 '22 23:05 steven-tey

@steven-tey So I figured out what the issue was.

It was in my getStaticProps

export async function getStaticProps({ params: { site } }) {
  try {
    console.log({ site });
    const { data: siteRes } = await axios.get(
      `${process.env.NEXT_PUBLIC_SERVER_URL}/api/site/subdomain/${site}`
    );
    console.log(siteRes);

    return {
      props: {
        site: siteRes,
      },
      revalidate: 3600,
    };
  } catch (err) {
    console.log("getstaticprops catch error = ");
    console.log(err);
    return {
      props: {
        data: {},
      },
    };
  }
}

The site param sends the entire url like subdomain.leavewithaweb.site to my API server instead of just subdomain

On my localhost it sends just subdomain and not the entire url.

I fixed it by parsing the string on my api but that's just a quick fix.

Any idea why on vercel production it's sending the entire url and not just the subdomain?

The cors error isn't a big deal and not involved in that page.

albertkimdev avatar May 11 '22 14:05 albertkimdev

@albertkimdev Ahhh gotcha! Do you know what the currentHost value is here inside your _middleware.js file?

  const currentHost =
    process.env.NODE_ENV === "production" && process.env.VERCEL === "1"
      ? // You have to replace ".vercel.pub" with your own domain if you deploy this example under your domain.
        // You can use wildcard subdomains on .vercel.app links that are associated with your Vercel team slug
        // in this case, our team slug is "platformize", thus *.platformize.vercel.app works
        hostname.replace(`.leavewithaweb.site`, "")
      : hostname.replace(`.localhost:3000`, "");

By right you should've removed .leavewithaweb.site here, which leaves you with subdomain that you're rewriting to the dynamic route so I'm curious to see if that's not happening.

steven-tey avatar May 11 '22 22:05 steven-tey

@steven-tey

image

When I visit https://12345.leavewithaweb.site/ and log my currenthost, pathname and host this is what I see.

albertkimdev avatar May 14 '22 03:05 albertkimdev

@steven-tey Maybe it's because process.env.NODE_ENV === "production" && process.env.VERCEL === "1" one of these statements isn't true?

albertkimdev avatar May 14 '22 03:05 albertkimdev

@steven-tey So it looks like process.env.VERCEL is undefined in my vercel project.

Is that env variable important? Can I remove it?

albertkimdev avatar May 16 '22 14:05 albertkimdev

Hey @albertkimdev! So sorry for the late response – this should've been fixed with our new middleware here. Please try it out and let me know if it works!

I'll close this issue for now but feel free to reopen it if there are any other issues!

steven-tey avatar Aug 12 '22 15:08 steven-tey