NextJS x Typescript - Integration & Troubleshooting

"next": "9.4.4"

Deployments

API not work on Git Pages

TLDR: NextJS API needs dynamic server, check Vercel instead of Git Pages

ref: https://github.com/vercel/next.js/issues/9366#issuecomment-552212621

GitHub pages is a hosting provider for static pages. You can't host APIs on it. If you really want to host on GitHub pages you'll want to use https://github.com/zeit/next.js#static-html-export and not use API routes.

ZEIT Now allows you to use both static, dynamic and API routes in one application, so I would recommend having a look at that.

Please make it easy to get up and running with GitHub pages even if you want them to use Now instead.

We can't make GitHub pages support API routes, dynamic rendering etc. It's only for static files. Deploying to GitHub pages / static hosts is covered by next export

Styles

NextJS Custom Font

Until next@9.4 , it is necessary to install extra loader for custom fonts.

Include the font

Use next/Head tag to add a font, put your font files in public/fonts _document.tsx

class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          // <link
          //   rel="preload"
          //   href="/fonts/noto-sans-v9-latin-regular.woff2"
          //   as="font"
          //   crossOrigin=""
          // />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Prepare the font-face

Pure CSS or Scoped CSS:

@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/noto-sans-v9-latin-regular.woff2');
  font-weight: bold;
  font-style: normal;
  font-display: swap;
}

Material UI SCSS:

const theme = createMuiTheme({
  overrides: {
    MuiCssBaseline: {
      "@global": {
        "@font-face": {
          fontFamily: "Cascadia",
          src: "url(\"/fonts/Cascadia.woff2\")",
        },
      },
    },
  },
  typography: {
    fontSize: 14,
    fontFamily: [
      "Cascadia", // your custom font here
      "Source Han Sans SC",
      "Noto Sans CJK SC",
      "HanHei SC",
      "-apple-system",
      "BlinkMacSystemFont",
      "\"Segoe UI\"",
      "Roboto",
      "\"Helvetica Neue\"",
      "Arial",
      "sans-serif",
      "\"Apple Color Emoji\"",
      "\"Segoe UI Emoji\"",
      "\"Segoe UI Symbol\"",
    ].join(","),
  },
});

Debugging

"dev": "NODE_OPTIONS='--inspect' next dev"

In Windows, use cross-env instead:

See 'NODE_OPTIONS' is not recognized as an internal or external command, operable program or batch file.

Once you open a new tab in Google Chrome and go to chrome://inspect, you should see your Next.js application inside the "Remote Target" section. Now click "inspect" to open a screen that will be your debugging environment from now on.

'NODE_OPTIONS' is not recognized as an internal or external command, operable program or batch file.

Windows 10 Issue

npm i cross-env -S -D

{
    "name": "your-app",
    "version": "0.0.0",
    "scripts": {
    ……
    "start": "cross-env NODE_OPTIONS='--inspect' next dev -p 3001",
    }
}

Troubleshooting

The default export is not a React Component in page

Server Error
Error: The default export is not a React Component in page

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Add a default export instead of normal export:

DO NOT DO THIS:

export const Comics = (): JSX.Element => {
 ……
};

DO THIS:

const Comics = (): JSX.Element => {
 ……
};

export default Comics

这个其实是后期版本的用法改变了, 需要将 Link 这样写

<Link href={{pathname:'/',query:{name:'demo',id:1}}}>
    <a>xxx</a>
</Link>

另外如果 a tag 不写 href 的话可能会报 eslint 警告:

The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.mdeslintjsx-a11y/anchor-is-valid

在 Eslint 配置文件将其改为不提示即可:

  "jsx-a11y/anchor-is-valid": [0]

If the child is a custom component that wraps an tag

如果 Link 里面使用了自定义组件那么就要传递一个 passHref

<Link href={chip.link || "#"} passHref>
  <Chip
    key={title}
    size="small"
    color={chip.title === highlight ? "primary" : "default"}
    label={ `${title} (${count})` }
  />
</Link>