-
Hi there, I essentially want to know how would you implement a statically generated website/app where you would have routes like:
Knowing that dashboard/settings/team all share the same layout/nav and only the content changes. I am trying to wrap my head around the right solution but unsure if it should be:
Then for the layout itself, in both solutions, not sure what to apply. Let me know! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 8 replies
-
Here's my first approach: /app/[...organization].js import React from "react";
import dynamic from "next/dynamic";
import { useRouter } from "next/router";
import AppLayout from "components/AppLayout";
const Components = {
dashboard: dynamic(() => import("components/organization/Dashboard")),
settings: dynamic(() => import("components/organization/Settings")),
};
export default function Organization() {
const router = useRouter();
// /app/zeit/dashboard
const query = router?.query?.organization;
const Component = Components[query?.[1]];
if (query === undefined) {
return <div>Loading</div>;
}
if (Component === undefined) {
router.push("/404");
return;
}
return (
<AppLayout>
<Component />
</AppLayout>
);
} This works, given you create links this way: <Link
href="/app/[...organization]/dashboard"
as={`/app/${router.query.organization[0]}/dashboard`}
/> But I am not quite sure this is a good way to do it. Especially because the navigation seems slower. I have read https://adamwathan.me/2019/10/17/persistent-layout-patterns-in-nextjs/ but was not able to apply the same patterns here. Let me know! Shameless random ping for help: @adamwathan @flaviocopes |
Beta Was this translation helpful? Give feedback.
-
Ok now solved I believe, here's how to do it properly (? please confirm :D): pages/_app.js: import React from "react";
import dynamic from "next/dynamic";
const layouts = {
AppLayout: dynamic(() => import("../components/layouts/AppLayout")),
Main: function Main({ children }) {
return <div>{children}</div>;
},
};
function MyApp({ Component, pageProps }) {
const Layout = layouts[Component.layout || "Main"];
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp; components/layouts/AppLayout.js: export default function AppLayout({children}) {
return <>{children}</>
} pages/app/[organization]/dashboard.js: function Dashboard() {
return <div>Dashboard</div>;
}
Dashboard.layout = "AppLayout";
export default Dashboard; pages/app/[organization]/settings.js: function Settings() {
return <div>Settings</div>;
}
Settings.layout = "AppLayout";
export default Settings; components/Sidebar.js import Link from "next/link";
export default function Sidebar() {
return (
<nav>
<Link
href="/app/[organization]/dashboard"
as={`/app/${router.query.organization}/dashboard`}
/>
<Link
href="/app/[organization]/settings"
as={`/app/${router.query.organization}/settings`}
/>
</nav>
)
} It works pretty well and the navigation is as performant as you would expect from a Next.js application. |
Beta Was this translation helpful? Give feedback.
-
Why not just change the layout in the slug file? // _app.js
class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return (
<AppLayout> // This is the main layout like header and footer
<Component {...pageProps} />
</AppLayout>
)
}
} And then the slug file const Page = props => {
const router = useRouter()
if (router.asPath == '/something/something') {
return (
<div class="some-other-layout">
<h1>Title</h1>
</div>
)
}
return (
<div class="something">
<h1>Title</h1>
</div>
)
} |
Beta Was this translation helpful? Give feedback.
Ok now solved I believe, here's how to do it properly (? please confirm :D):
pages/_app.js:
components/layouts/AppLayout.js:
pages/app/[organization]/dashboard.js: