Debugging and Resolving Complex Issues in Next.js Applications
September 6, 2025 Next.js Debugging Hydration Error Internationalization Favicon
Debugging and Resolving Complex Issues in Next.js Applications
Introduction
This article details the process of identifying and resolving multiple technical issues that occurred in a Next.js application through interaction with the Gemini CLI. In particular, a deep understanding of Next.js's rendering mechanisms and internationalization was required. With the assistance of the Gemini CLI, we delved into each problem one by one and applied solutions.
Problem 1: Resolving Hydration Errors
Initial Symptoms
Upon initial loading of the application, especially when directly accessing the top page, the following Hydration error was displayed in the console:
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Expected server HTML to contain a matching <div> in <a>.
This error exhibited strange behavior, disappearing after a page transition.
Cause and Trial and Error
This error occurs when the HTML rendered on the server-side does not match the HTML hydrated on the client-side. The specific message, indicating a <div> nested within an <a> tag, provided a clue.
-
Nesting issue within
Linkcomponent inJobCard.tsx:- Initially, it was thought that the
Linkcomponent withinsrc/components/JobCard.tsxwas rendering an<a>tag and directly containing a<div>as its child element. In HTML semantics, block-level elements cannot be directly nested within an<a>tag. - We attempted a fix using the
legacyBehaviorproperty, explicitly passing an<a>tag as a child ofLinkand placing the<div>inside that<a>tag. - However, this fix caused a syntax error:
Unexpected token Link, requiring manual correction. Ultimately, another problem emerged: an<a>tag nested within an<a>tag.
- Initially, it was thought that the
-
Nested
<a>tag withinJobCard.tsx:- Within
JobCard.tsx, an<a>tag displaying the job poster's email address as a link was nested within an<a>tag rendered by the outerLinkcomponent. - This was resolved by changing it to a
<span>tag, eliminating the nested<a>tag issue.
- Within
-
Use of
key={Date.now()}:src/app/[locale]/page.tsxhadkey={Date.now()}set for theJobListingClientcomponent.Date.now()generates different values on the server and client, which can cause Hydration errors.- This
keyproperty was removed.
-
dangerouslySetInnerHTMLinAnalytics.tsx:- The Google Analytics tracking code within
src/components/Analytics.tsxuseddangerouslySetInnerHTMLto directly embedwindow.location.pathname. Since thewindowobject does not exist on the server-side, the HTML generated on the server and client differed, causing Hydration errors. - This was fixed by using the
usePathname()hook to get the path and embedding it withindangerouslySetInnerHTML.
- The Google Analytics tracking code within
-
Duplicate
i18ninitialization logic inHeader.tsx:src/components/Header.tsxwas re-initializing thei18ninstance withcreateInstance(). This was a duplication of the process already performed inlayout.tsxand could potentially cause Hydration errors.- The
i18ninitialization logic was removed fromHeader.tsx, anduseTranslationhook was used instead.
-
Double import of
useTranslationinHeader.tsx:- During the above fix, an error occurred where
useTranslationwas imported twice. This was a simple import duplication and was corrected.
- During the above fix, an error occurred where
-
Use of
I18nProviderinlayout.tsx:src/app/[locale]/layout.tsxwas not usingreact-i18next'sI18nProvider. When usinguseTranslationin client components,I18nProvidermust be present higher up in the component tree.- This was fixed by using
I18nProviderinlayout.tsx.
Final Resolution
As a result of applying the above multiple fixes, Hydration errors in the development environment were resolved. However, warnings such as Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed may remain, but these are usually due to browser extensions and do not affect the application's functionality.
Problem 2: Resolving Favicon 404 Issue
Initial Symptoms
When accessing the application, a GET /favicon.ico 404 error was displayed in the console, and the favicon was not displayed correctly.
Cause and Solution
In Next.js App Router, placing src/app/icon.png automatically recognizes it as a favicon, but browsers may still request favicon.ico. Also, the absence of favicon.ico in the public directory was the cause.
- Deletion of
src/app/icon.png: To avoid conflicts with the favicon setting in theappdirectory,src/app/icon.pngwas deleted. - Placement of
public/favicon.ico:konnichiwork_favicon.pngwhich was in the project root, was moved to thepublicdirectory and converted tofavicon.icoformat and placed there (this conversion and placement was a manual operation by the user). - Deletion of favicon link from
layout.tsx: Sincepublic/favicon.icois automatically recognized, the favicon link explicitly added tosrc/app/[locale]/layout.tsxwas deleted.
With these fixes, the favicon is now displayed correctly.
Problem 3: Internationalization of Image Upload Button on Post Job Page
Initial Symptoms
The text of the image upload button on the Post job page (e.g., "No file chosen") was displayed only in Japanese and was not internationalized.
Cause and Solution
The default display of input type="file" depends on the browser, so it cannot be directly internationalized.
- Deletion of "No file chosen" display: The previously added message displayed when no file was selected was removed.
- Implementation of custom file input field:
- The original
input type="file"was hidden, and a custom UI combininglabelandspanelements was implemented. - The
labelwas set to displayt('form_select_file', 'Select file'), and thespanwas set to displayt('form_no_file_chosen', 'No file chosen')ort('form_file_uploaded', 'File uploaded').
- The original
- Addition of translation keys: New translation keys
form_select_file,form_no_file_chosen,form_file_uploadedwere added topublic/locales/{lang}/common.jsonfor each language (this was a manual operation by the user).
This improved the display by internationalizing the text of the image upload button.
Problem 4: Posted Job Not Translated Issue
Initial Symptoms
On the job details page, posted job information was displayed without being translated into the language selected by the user.
Cause and Solution
This issue is related to the translation logic using the Google Cloud Translation API.
- Addition of debug logs: Debug logs were added to
src/app/api/translate/route.tsto check the API key settings, success/failure of API calls, and response content. - Verification of environment variables and API: It was necessary to confirm whether
GOOGLE_TRANSLATE_API_KEYwas correctly set, whether the API key was valid, whether the Translation API was enabled in Google Cloud Platform, and whether there were any network connection issues.
Current Status: The addition of debug logs has been completed, but this issue has not been fully resolved yet. User confirmation of GOOGLE_TRANSLATE_API_KEY settings and server console logs is required. Based on this information, further debugging and application of solutions will be necessary.
Conclusion
Through collaboration with the Gemini CLI, we were able to identify and resolve a wide range of complex issues in the Next.js application, including Hydration errors, internationalization, favicons, and job translation. Debugging Hydration errors was particularly challenging, but by deeply understanding the role of each component and Next.js's rendering lifecycle, we were able to pinpoint the root cause. Although some issues required manual user intervention, the collaboration with the CLI enabled an efficient debugging and correction process.