Next.JS useRouter will only returns an empty object for a dynamic route

Viewed 1483

I am making a bit of a specialized calendar application in Next.JS and I am have some problems with dynamic routing that I can't seem to figure out. I have two similar pages with similar routes, where one is working perfectly fine and the other not working at all.

First page (working):

// pages/date/[year]/[month]/[dayOfMonth].tsx
import { useRouter } from "next/router";
import { Day } from "../../../../components/Day";

type StringQueryParams = Record<keyof QueryParams, string>;

interface QueryParams {
  year: number;
  month: number;
  dayOfMonth: number;
}

const transformParams = ({ year, month, dayOfMonth }: StringQueryParams): QueryParams => ({
  year: parseInt(year),
  month: parseInt(month),
  dayOfMonth: parseInt(dayOfMonth),
});

const DayPage: React.FC = () => {
  const { query } = useRouter();
  const params = transformParams(query as StringQueryParams);
  return <Day {...params} />;
};

export default DayPage;

Second page (not working)

// pages/date/[year]/[month].tsx
import { useRouter } from "next/router";
import { Month } from "../../../components/Month";
import { validateMonth } from "../../../lib/month";

type StringQueryParams = Record<keyof QueryParams, string>;

interface QueryParams {
  month: string;
  year: number;
}

const MonthDisplay: React.FC = () => {
  const router = useRouter();
  debugger;
  const { query } = router;
  const { month: rawMonth, year: rawYear } = query as StringQueryParams;
  console.log("query:", query);
  console.log("router:", router);
  const month = validateMonth(rawMonth);
  const year = parseInt(rawYear);

  return <Month name={month} year={year} />;
};

export default MonthDisplay;

With output

query: {}
router: ServerRouter {
  route: '/date/[year]/[month]',
  pathname: '/date/[year]/[month]',
  query: {},
  asPath: '/date/[year]/[month]',
  basePath: '',
  events: undefined,
  isFallback: false
}

I cannot for the life of me seem to figure out why the dynamic routing for the second page is not working at all, and not returning any query from the useRouter() hook.

2 Answers

Moving pages/date/[year]/[month].tsx to pages/date/[year]/[month]/index.tsx should work

Your tree should be look like this

Pages
  [years]
    [months]
      index.tsx --> your 2nd page
      [days]
        indes.tsx --> your first page

enter image description here

Documentation

Related