TinaCMS/Nextjs github pages 404 when accessing root url in - next.js

I just deployed a TinaCMS page on github pages using github actions. It seems to work fine except on initial access to the root URL. On this initial load, Nextjs renders a 404 error page with a link 'Return to home'. When clicking this link, the browser's URL is still the root URL and the home page is rendered correctly.
when I access a sub page like example.com/posts directly, the page is rendered correctly.
when I do a build and export locally and open the files using a local nginx server, the home page is rendered correctly on initial access.
in my next.config.js a have the following:
async rewrites() {
return [
{
source: "/",
destination: "/home",
} ...
so what could the problem be in conjunction with github pages?
the complete source code is here: https://github.com/mtnstar/web
the page is accessible on https://mtnstar.net

I found a temporary fix, although the 404 page is flashing up for a second and then the right home age is rendered.
so I added a useEffect hook to initially redirecting to the browser current url.
import React from "react";
import "../styles.css";
import { useRouter } from 'next/router'
const App = ({ Component, pageProps }) => {
const router = useRouter();
React.useEffect(()=>{
router.push(window.location.href)
},[])
return <Component {...pageProps} />;
};
so another way to permanently fixing this would be appreciated

Related

nextjs reload page with Link component

I have a simple nextjs 13 application (appDir) with 2 pages and a <Link/> component navigation.
first page Home - static
second page Test - receiving dynamic random content on the server side (fetch) from a third-party source.
Problem: When the application is rendered everything works fine, but when I try to switch between pages, my test page shows the old content, I can refresh the browser to get the actual data, is very similar to navigating through regular links <a/>, but i need without reloading the entire application.
Q: How can I force nextjs 13 to reload the Test page when I switch between pages with <Link/> component?
// src/components/navbar.tsx
'use client'
import {usePathname} from "next/navigation";
import Link from "next/link";
const navItems = [
{text: 'Home', href: '/'},
{text: 'Test', href: '/test'}
];
const Navbar = () => {
const pathname = usePathname();
return <nav className="nav nav-masthead justify-content-center float-md-end">
{navItems.map((item: { text: string, href: string, link?: boolean }, idx: number) => (
<Link key={idx} href={item.href} className={`nav-link${item.href === pathname ? ' active' : ''}`}>
{item.text}
</Link>
)
)}
</nav>
}
export default Navbar;
// src/app/test/page.tsx
import * as crypto from "crypto";
const getData = async () => {
const res = await fetch('http://localhost:3000/random-data', {cache: 'no-store'});
if (!res.ok) {
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function Page() {
return <p>{crypto.createHash('sha256').update(JSON.stringify(await getData())).digest('hex')}</p>
};
I've recently asked about this same topic on their feedback discussion on github: https://github.com/vercel/next.js/discussions/41745?sort=new#discussioncomment-4620262
The cause of the problem is Link is only doing client side navigation and seems to serve a cached state of the previously visited component. You'll notice that the client never calls back to the server and thus the server component never runs the second time.
I've been searching for days, but haven't found a way to force Link to reload or force refresh the component to re-render.
My conclusion is that if you have dynamic data that needs to refreshed periodically, it's best to render it in a client component and not use a server component for now.
Also, if you'd like to use Suspense, you'll need to use a library like SWR or React Query for any client side data fetching.

NextJs app directory - page gets remounted when slug changes

I was trying to migrate my nextjs application to app directory, but I found a weird behaviour.
When I have a route in the pages folder like this:
// `pages/test/[slug]/index.tsx`
export default function Page() {
useEffect(() => {
console.log('mount')
return () => {
console.log('unmount')
}
}, [])
return <>
<Link href="/test/1">1</Link>
<Link href="/test/2">2</Link>
</>
}
if I change the page by clicking one of the links, the slug changes, but component doesn't remount. However, when I move this file to app/test/[slug]/page.tsx and mark the file with 'use client';, clicking the link unmounts page component and then mounts it again.
Is this expected behaviour? If so how can I achieve behaviour from pages directory in app?

Nextjs nested routing not found

I'm trying to create a nested route inside my nextjs project, but i'm receiving a 404 page not found when trying to request the page.
I have a route named /dashboard/repository/blender where blender is a dynamic name that the user can input and that works fine.
But the next step is then to create a subpage for that dynamic route which is named tags, and that's where I receive the 404. (/dashboard/repository/blender/tags)
Here's a screenshot of what i've tried to achieve the tags nested routing
Secondly I have also tried doing the following
What can I do to achieve this ?
Try that structure please
dashboard (folder)
-repository (folder)
--[blender] (folder)
----tags.tsx (file)
example urls
/dashboard/repository/blender/tags
/dashboard/repository/surrender/tags
...
In your component, you can get it like below
tags.tsx
import { useRouter } from 'next/router'
const C = () => {
const router = useRouter()
const { blender } = router.query;
console.log(blender)
}
Solved it with
- /dashboard/repository/[repository]/index.js
- /dashboard/repository/[repository]/tags.js

NextJS route gives 404 when not using Link

I have a Next.js page, where the pages are statically generated (using next export). It's a dynamic route, but I will only fetch data on the client after the initial page load (in a useEffect).
The path is something like: /pages/foo/[id].tsx. This is in fact the only route which is going to exist.
My problem is:
If I access the URL directly (e.g. typing in https://mysite.fake/foo/1337 into the URL bar) I get a 404.
If I navigate to that route using a <Link /> it does work as expected
If I then reload the page, I get a 404 again.
On local dev, it works fine. The problem only exists when deployed.
The page in question is using the router.query, but I have the same problem with a completely static page (e.g. just /pages/bar/baz.tsx).
Example:
export const Home: NextPage = () => {
const router = useRouter()
const { id } = router.query
const headerText = id ? `Hello ${id.toString()}` : ''
// in a later iteration, I will use the query id to fetch data in a useEffect
return <h1>{headerText}</h1>
}
As far as I understand from the Next.js documentation on dynamic routing and data fetching this should be possible to do.
My next.config.js is very bare:
/** #type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,
}
What am I doing wrong?

NextJS and Keycloak integration (Opt-out of Automatic Static Optimization issue)

I am trying to integrate keycloak with NextJS.
The library that I am using is: https://www.npmjs.com/package/#react-keycloak/ssr
In documentation they said to wrap SSRKeycloakProvider component over the App component in _app.tsx file.
Like this:
function MyApp({ Component, pageProps, cookies }: AppProps & InitialProps) {
return (
<SSRKeycloakProvider
keycloakConfig={keycloakCfg}
persistor={SSRCookies(cookies)}
>
<Component {...pageProps} />
</SSRKeycloakProvider>
)
}
...
MyApp.getInitialProps = async (context: AppContext) => {
// Extract cookies from AppContext
return {
cookies: parseCookies(context?.ctx?.req),
};
};
I have tested it and everything works fine, until I pushed my changes to gitlab and pipeline failed with error message:
Warning: You have opted-out of Automatic Static Optimization due to
getInitialProps in pages/_app. This does not opt-out pages with
getStaticProps Read more:
https://nextjs.org/docs/messages/opt-out-auto-static-optimization
Seems that this will cause that all pages without getStaticProps() method will be server side rendered. How to avoid that?
Should I create one more component which will look similiar like this MyApp(), and wrap it only over the pages that require keycloak authentification? (and then remove that SSRKeycloakProvider from MyApp and at this to that new one)

Resources