Reputation: 413
Problem: In my Next.js 14 application, I have a loading.js
component intended solely to display a loading indicator. However, the Navbar
and Footer
components from the RootLayout
inside the layout.js are also appearing when loading.js
is rendered. I need the loading.js
to display only the loading indicator without the navbar or footer.
Expected Behavior: The loading.js
should only display a loading spinner when active. Other components like the navbar and footer should not be visible until the data is fully loaded and the main content begins to render.
Current Behavior: Despite its setup, the loading.js
still displays the navbar and footer defined in RootLayout
inside the layout.js
.
layout.js
import "./globals.css";
import Footer from "@/components/Footer";
import Navbar from "@/components/nav-bar";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Navbar />
{children}
<Footer />
</body>
</html>
);
}
loading.js
import Loader from "@/components/loader/loader";
export default function LoaderPage() {
return <Loader />;
}
How can I modify the LoaderPage
in loading.js
or RootLayout
in layout.js
so that only the Loader is visible during loading, without the navbar and footer components without changing the component to client component?
Upvotes: 0
Views: 413
Reputation: 886
Everything at the same level will be wrapped by the layout, it's expected.
The solution is to use Route Groups. Usually the root layout does not contain components but only providers because they affect the whole app.
But of course you may want to have a layout for the home page. To do that we need a route group. Your app will look like this:
src/
└── app/
├── (main)/
│ ├── page.jsx # moved
│ └── layout.jsx # navbar and footer here
├── layout.jsx # metadata here
└── loading.jsx # same
The page.jsx inside (main) will be wrapped by the root layout and his sibling, and loading.jsx will be wrapped only by the root layout solving your problem (:
Result
#app/layout.jsx
import "./globals.css";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}
#app/(main)layout.jsx
import Footer from "@/components/Footer";
import Navbar from "@/components/nav-bar";
export default function Layout({ children }) {
return (
<>
<Navbar />
{children}
<Footer />
</>
);
}
Upvotes: 1