Conditional render classes based on url in Next.js - next.js

I'm trying to show different navigations based on if it is the "Homepage" or if it is a page that contains "docs" (e.g. docs/1, docs/2, docs/3) in its URL.
I'm just getting blanks on the "docs"-case - it feels like I am missing something here?
Here's my code so far:
const router = useRouter()
const path = router?.asPath
if (path === '/docs/') {
return (
<>
<Head>
<title>{pageTitle}</title>
{description && <meta name="description" content={description} />}
</Head>
<Layout
navigation={navigation1}
title={title}
tableOfContents={tableOfContents}
>
<Component {...pageProps} />
</Layout>
</>
)
}
if (path === '/') {
return (
<>
<Head>
<title>{pageTitle}</title>
{description && <meta name="description" content={description} />}
</Head>
<Layout
navigation={navigation}
title={title}
tableOfContents={tableOfContents}
>
<Component {...pageProps} />
</Layout>
</>
)
}

NextJS has a built-in route system. You can just create a docs.js file in the pages folder. You can either create different navigations directly in /pages/docs.js or a dynamic component for it.
Here is more about routing https://nextjs.org/docs/routing/introduction
Hope this answers your question :)

I'm not sure if you have fixed this but I have completed the same method with the following code:
import { useRouter } from 'next/router';
const ComponentName = () => {
const router = useRouter();
const { pathname } = router;
if (pathname.includes('/')) {
// Add home component
} else {
// Add another component instead
}
}
export default ComponentName
You can then use conditional statements to check what the path is just like you were doing.
- Tested with Next JS V13

Related

how to get query params inside getInitialProps?

Here is my code I want to update the meta content based on the query parameter.
For Example localhost:3000/in
I need to fetch the meta content for India and need to update on .
But I can't fetch the query parameters on getInitialProps. how to get query params inside getInitialProps?
function StartApp({ Component, pageProps, initialAsideLeftHandler }) {
return <>
<Provider store={store}>
<Head>
<title>{initialAsideLeftHandler[2].values}</title>
<meta name="title" content={initialAsideLeftHandler[2].values} />
<meta name="description" content={initialAsideLeftHandler[1].values} />
<link rel="icon" href="/favicon.ico" />
</Head>
<Header/>
<Component {...pageProps} />
<Footer />
</Provider>
</>
}
StartApp.getInitialProps = async ({query}) => {
let parameter = {
"countryCode": "in",
"slug": "home",
}
let data = await getMetaContent(parameter);
return { initialAsideLeftHandler: data }
}

why am I not able to show the data I am fetching from graphcms using next.js?

I am following a tutorial to create a blog using headless cms with nextjs .
Even though api calls are working but it is not being rendered on the localhost.
following is the code in index.js :
import Head from "next/head";
import styles from "../styles/Home.module.css";
import { GraphQLClient, gql } from "graphql-request";
import BlogPost from "../components/BlogPost";
const graphcms = new GraphQLClient(
"https://api-ap-south-1.graphcms.com/v2/cl4plwtca25zv01z4apa66xo8/master"
);
const query = gql`
{
posts {
id
title
date
slug
content {
html
}
author {
name
picture {
url
}
}
coverImage {
url
}
}
}
`;
export async function getStaticProps() {
const { posts } = await graphcms.request(query);
return {
props: {
posts,
},
revalidate: 10,
};
}
export default function Home({ posts }) {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
{posts.map((post) => {
<BlogPost
title={post.title}
author={post.author}
slug={post.slug}
coverImage={post.coverImage}
date={post.date}
/>;
})}
</main>
</div>
);
}
following is the code in BlogPost.js:
import Link from "next/link";
import styles from "../styles/BlogPost.module.css";
export default function BlogPost({ title, author, coverImage, date, slug }) {
return (
<div className={styles.card}>
<Link href={`/posts/&{slug}`}>
<div className={styles.imgContainer}>
<img src={coverImage.url} alt=" " />
</div>
</Link>
<div className={styles.text}>
<h2>{title}</h2>
<div className={styles.details}>
<div style={style.author}>
<img src={author.picture.url} alt="" />
</div>
</div>
</div>
</div>
);
}
with the above code it is expected to show everything that is on graphcms but I am only getting a blank screen. Please find the problem here!
You're not returning anything in your .map (Assuming you really are getting data)
{posts.map((post) => {
return <BlogPost <---- notice the `return` keyword
title={post.title}
author={post.author}
slug={post.slug}
coverImage={post.coverImage}
date={post.date}
/>;
})}

Nextjs Script tag not working ReferenceError: alertShow is not defined

I tried soo many time with different ways but it is showing the same error please guide me.
import Head from 'next/head'
import Script from 'next/script'
export default function Home() {
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<h1>hii</h1>
<button onClick={alertShow}>Click Me</button>
<Script src='../public/test.js'></Script>
</>
)
}
You can see something simillar in the logs This is how I did it:
test.js file:
window.alertShow = { myAlert: () => { alert('you clicked me'); } };
MyAppFile:
import React, { useState } from 'react';
import Script from 'next/script';
import '../styles/globals.css';
function MyApp() {
const [scriptAlert, setScriptAlert] = useState();
return (
<>
<Script
src="/test.js"
onLoad={() => {
setScriptAlert(window.alertShow);
}}
/>
<button type="button" onClick={() => scriptAlert && scriptAlert.myAlert()}>Click Me</button>
</>
);
}
export default MyApp;

can't solve next-head-count is missing error

I know this is a duplicate, but I couldn't solve my problem with those answers. so here is my code:
//_document.tsx
import Document, { Html, Head, Main, NextScript } from "next/document";
export default class MyDocument extends Document {
render() {
return (
<Html>
<Head />
<body dir="rtl">
<Main />
<NextScript />
</body>
</Html>
);
}
}
//_app.tsx
import "../styles/globals.scss";
import Head from "next/head";
import type { AppProps } from "next/app";
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<Head>
<title>Bitbarg</title>
<meta name="description" content="Descriptions" />
<link rel="icon" href="/favicon.ico" />
<body dir="rtl" />
</Head>
<Component {...pageProps} />
</>
);
}
export default MyApp;
I'm still getting this error.
I tried taking all _app.tsx Head tag in _document.tsx, this removed the error but I'm getting new error as:
Titles should be defined at the page-level using next/head.
I tried only putting code bellow in _app.tsx, but it gives me the next-head-count error again.
<Head>
<title>Bitbarg</title>
</Head>
Resolved when I removed
from _app.js as I was using it already in _document.js

How to exclude a default component from _app.js from rendering in the slug

I have read through the documentations of Next.Js and I understood that by creating a _app.js file it will override the default App.js file, So those component in the _app.js file will show on every page and that's what I need, But I also need to exclude some of those components from rendering in the slug, Like the Header or Footer for example I wanna show them on all pages except for the slug, How can I do that ?
here is my code for the _app.js
import React from 'react'
import Head from 'next/head';
import { ThemeProvider } from '#material-ui/core/styles';
import Header from '#/components/Header/Header'
import theme from '#/theme/theme';
function MyApp({ Component, pageProps }) {
return (
<Head>
<title>My App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<ThemeProvider theme={theme}>
<Header />
<main>
<Component {...pageProps} />
</main>
</ThemeProvider>
)
}
And this is my slug
import React from 'react'
const MyAccounts = ({ data }) => {
const post = data && data.posts[0]
return (
<>
<div>
<article>
{post.feature_image ?
<figure >
<img src={post.feature_image} alt={post.title} />
</figure> : null}
<section >
<h1>{post.title}</h1>
</section>
</article>
</div>
</>
)
}
export default MyAccounts
So in this Code I dont want the component Head to show in my slug, How do I exclude it ?
In the _app.js you have the pageProps, you can leverage that. Set some property in it and render based on that.
Something like:
function MyApp({ Component, pageProps }) {
return (
<Head>
<title>My App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<ThemeProvider theme={theme}>
{pageProps.noLayout ? <></> : <Header />}
<main>
<Component {...pageProps} />
</main>
</ThemeProvider>
)
}
and then on the page add for example:
export async function getStaticProps(context) {
return {
props: { noLayout: true },
}
}

Resources