nextra icon indicating copy to clipboard operation
nextra copied to clipboard

Possible to augment/extend `nextra-theme-docs`?

Open brianjenkins94 opened this issue 2 years ago • 4 comments

Given a Next.js application configured with the Nextra plugin like so:

// /next.config.js

module.exports = (require("nextra")({
	"theme": "./layouts/docs"
}))();

This "works":

// /layouts/docs/index.tsx

import nextra from "nextra-theme-docs";

export default function Layout(pageProps) {
	const Nextra = nextra(pageProps, {
		"footerText": "Copyright ©. All rights reserved."
	});

	return Nextra;
}

Would it be possible to do something like this?:

// /layouts/docs/index.tsx

import nextra from "nextra-theme-docs";

export default function Layout(pageProps) {
	const Nextra = nextra(pageProps, {
		"footerText": "Copyright ©. All rights reserved."
	});

	return (
		<>
			<Head>
				<link href="../../node_modules/nextra-theme-docs/style.css" rel="stylesheet" />
			</Head>

			{Nextra}
		</>
	);
}

This would allow me to base my theme off of the out-of-the-box nextra-theme-docs theme but also make changes to the default styling/layout in a convenient way.

I'll see if I can put together a gist.

brianjenkins94 avatar May 06 '22 12:05 brianjenkins94

Minimal sample that reproduces the issue (apparently gists can't do folders):

nextra-459.zip (just 10 short files, most of which are boilerplate)

To reproduce the issue:

  1. On a non-Windows machine (Windows file paths break it)

  2. cd nextra-459

  3. npm install

  4. npm run dev

  5. Navigate to http://localhost:3000/docs/test

brianjenkins94 avatar May 06 '22 14:05 brianjenkins94

Very nearly got it:

// /layouts/docs/index.tsx

import "nextra-theme-docs/style.css";
import nextra from "nextra-theme-docs";

export default function Layout(pageProps) {
	const Nextra = nextra(pageProps, {
		"head": (
			<>
				<link href="/css/nextra-overrides.css" rel="stylesheet" />
			</>
		),
		"footerText": "Copyright ©. All rights reserved."
	});

	return Nextra;
}

I just need to sort out my _app.tsx since for some reason NextraPage doesn't have a getLayout on it when it gets to my custom Layout function. (by all appearances it should...)

brianjenkins94 avatar May 06 '22 18:05 brianjenkins94

I've gone with this for the time being:

// /pages/_app.tsx

import type { AppProps } from "next/app";
import Layout from "../layouts/default";
import Head from "next/head";

export default function App({ Component, pageProps }: AppProps) {
	if (Component.name === "NextraPage") {
		Component.getLayout = function(page) {
			return Component(page);
		};
	}

	const getLayout = Component["getLayout"] ?? function(page) { return <Layout children={page} />; };

	return (
		<>
			<Head>
				<meta name="viewport" content="width=device-width, initial-scale=1" />
			</Head>

			{getLayout(<Component {...pageProps} />)}
		</>
	);
}

But it would be nice if NextraPage had the getLayout function on it. I'm not actually sure why it doesn't.

brianjenkins94 avatar May 07 '22 15:05 brianjenkins94

Hey! I saw this issue listed on bounty source, is this issue still open to work on?

pratik9315 avatar Jul 02 '22 13:07 pratik9315