Next.js
Next.js + MDX
const withMDX = require('@next/mdx')({
extension: /\.(md|mdx)$/,
});
module.exports = withMDX({
// Pick up MDX files in the /pages/ directory
pageExtensions: ['js', 'jsx', 'md', 'mdx'],
});
Google Analytics
Add this to any of the <Head>
:
import Head from 'next/head';
import Script from 'next/script';
<Head>
<Script async src="https://www.googletagmanager.com/gtag/js?id=XXXXXXXX" />
<Script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'XXXXXXXX');
`,
}}
/>
</Head>;
Sitemap
Use nextjs-sitemap
package.
Image
Local image: no need to specify width
and height
since they are available at the build time.
import localImage from '/path/to/image.jpg';
import Image from 'next/image';
<Image src={localImage} />;
Remote image: need to specify width
and height
.
<Image src="http://example.com/image.png" width={400} height={500} />
How to use Node.js API vs Web API
Server-side only: Node.js API
To use path
, fs
, put them inside getStaticProps()
, which is called at the build time on the server-side but not on the client-side:
import { promises as fs } from 'fs';
import path from 'path';
export async function getStaticProps(context) {
const filepath = path.join(process.cwd(), 'path/to/file');
const content = (await fs.readFile(filepath)).toString();
return {
props: {
content: await Promise.all(content),
},
};
}
Client-side only: Web API
To use window
or other Web APIs, use the useEffect
hook, which only executes client-side:
import { useEffect } from 'react';
useEffect(() => {
// You now have access to `window`
}, []);
Get Window Height
As mentioned above, window
is available inside useEffect()
:
const [mapHeight, setMapHeight] = useState(0);
useEffect(() => {
setMapHeight(window.innerHeight - 100);
}, []);
Deployment
If your site is static, you can use next build && next export
to export the static HTML.
Otherwise Next.js has a built-in server. You can check Next.js's package.json
, it depends on express
.
Trouble Shooting
The default Firebase app already exists.
Solution: check if (!firebase.apps.length)
:
import firebase from 'firebase-admin';
import { initializeApp, cert } from 'firebase-admin/app';
if (!firebase.apps.length) {
initializeApp({
credential: cert(serviceAccount),
});
}
Undefined router
The result of const router = useRouter();
may be undefined at the first rendering.
Solution: check router.isReady
in useEffect
:
const router = useRouter();
useEffect(() => {
if (!router.isReady) return;
// ...
}, [router.isReady]);