π My Next.js Portfolio Was Invisible to Google & ChatGPT - Here's How I Fixed It
π Hey! I'm Dhruv Sheladiya, a Full Stack Developer working with the MERN Stack, React.js, Next.js & Node.js. This is the story of how I found out my own portfolio was basically invisible, and the 5 fixes that changed that. π¬
The Embarrassing Discovery
I Googled my own name. Here's what I found:
| What I expected | What actually happened |
|---|---|
| β My portfolio at the top | β Barely showing up |
| β A nice preview image | β No image at all |
| β ChatGPT knows who I am | β "I don't have information about that person" |
The site looked perfect in the browser. So what was going on? π€ π΅οΈ
The Root Cause: A Beautiful Page That Crawlers Saw as Empty
My portfolio has a cool animated loader, and the homepage is a client component:
"use client";
export default function Home() {
const [showLoader, setShowLoader] = useState(true);
return showLoader
? <Loader onComplete={() => setShowLoader(false)} />
: <MainContent />;
}
For real users? Totally fine. π
For crawlers? The HTML only contains the loader. No name. No heading. No links. π
| Visitor | Runs JavaScript? | What it saw |
|---|---|---|
| π§ Real user | β Yes | Full animated portfolio |
| π€ Googlebot | β οΈ Sometimes, slowly | Maybe the content, maybe just the loader |
| π§ AI crawlers (ChatGPT, Perplexity) | β Mostly no | An empty page |
π‘ Lesson #1: Always check your page without JavaScript. Run curl https://your-site.com or rightβclick → View Page Source. If your name isn't in there, crawlers probably can't see it either.
Fix #1: ServerβRender the Important Content
I didn't want to touch the UI, so I added a small, accessible profile block in layout.js, which is a Server Component. Tailwind's sr-only class makes it readable by screen readers and crawlers, but it doesn't change the design at all:
<body>
<div className="sr-only">
<h1>Dhruv Sheladiya - Full Stack Developer | MERN Stack | React.js Next.js & Node.js Expert</h1>
<p>Full Stack Developer from India specializing in React.js, Next.js and Node.js.</p>
<nav aria-label="Dhruv Sheladiya on the web">
<ul>
{SOCIALS.map((s) => (
<li key={s.href}>
<a href={s.href} rel="me noopener">
Dhruv Sheladiya on {s.label}
</a>
</li>
))}
</ul>
</nav>
</div>
{children}
</body>
β οΈ Important: Keep this content honest and identical to what's visible on the page.
β Hidden text stuffed with keywords = spam signal
β
Accessible text that matches your real content = fine
Fix #2: Structured Data That Connects All Your Profiles
Google builds a Knowledge Graph entry for people by connecting profiles that belong to the same person. The sameAs property in JSONβLD tells Google exactly which profiles are yours π
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Person",
"@id": "https://aboutdhruv.vercel.app/#person",
"name": "Dhruv Sheladiya",
"jobTitle": "Full Stack Developer",
"url": "https://aboutdhruv.vercel.app",
"sameAs": [
"https://www.upwork.com/freelancers/~0191c7eba12b27a044",
"https://www.linkedin.com/in/dhruv-sheladiya-a350582a6",
"https://github.com/Dhruv-1511",
"https://x.com/DhruvSheladiya2"
]
},
{
"@type": "ProfilePage",
"url": "https://aboutdhruv.vercel.app",
"mainEntity": {
"@id": "https://aboutdhruv.vercel.app/#person"
}
}
]
}
I also added <link rel="me"> tags in the <head> for every profile. GitHub and Mastodon use rel="me" for identity verification too. πͺͺ
π The secret sauce: this only works if it goes both ways. Your site links to your profiles β‘οΈ and every profile (GitHub, LinkedIn, Upwork, X…) links back to your site β¬ οΈ
Fix #3: My OG Image Was 1.7β―MB π±
My openGraph config said the image was 1200×630, but the real file was:
| β Before | β
After |
|---|---|
| Size: 1629 × 966 | Size: 1200 × 630 |
| Weight: 1.77β―MB | Weight: 80β―KB |
| Format: PNG | Format: JPEG (mozjpeg) |
| Preview showing? | Nope | Yes π |
I fixed it with a single command using sharp, which already comes with Next.js:
node -e "require('sharp')('public/ogimg.png').resize(1200,630,{fit:'cover'}).jpeg({quality:82,mozjpeg:true}).toFile('public/og.jpg')"
π§ Did you know? og:image is for social previews (WhatsApp, LinkedIn, X). Google doesn't use it for search thumbnails. It picks images from your page content and structured data, one more reason Fix #1 matters.
Fix #4: Nail the Next.js Metadata Basics
export const metadata = {
metadataBase: new URL("https://aboutdhruv.vercel.app"),
title: "Dhruv Sheladiya - Full Stack Developer | MERN Stack | React.js Next.js & Node.js Expert",
alternates: {
canonical: "/",
},
openGraph: {
type: "profile",
images: [{ url: "/og.jpg", width: 1200, height: 630 }],
},
robots: {
index: true,
follow: true,
googleBot: {
"max-image-preview": "large",
"max-snippet": -1,
},
},
};
| Rule | Why it matters |
|---|---|
| π₯ Name first in the title | People search your name, not your job title |
| π Same headline everywhere | My title matches my Upwork headline exactly, so search engines connect the dots |
| π― Canonical URL | Stops Google splitting ranking between duplicate URLs |
πΌοΈ max-image-preview: large |
Allows large image previews in results |
π€ max-snippet: -1 |
Gives Google permission to show full snippets |
Fix #5: Add llms.txt for AI Assistants
llms.txt is a newer convention: a plain Markdown file at /llms.txt that summarizes your site for AI tools. π Click to see what my llms.txt looks like:
# Dhruv Sheladiya
> Dhruv Sheladiya is a Full Stack Developer from India - MERN Stack |
> React.js, Next.js & Node.js Expert. Portfolio: https://aboutdhruv.vercel.app
## Skills
- Frontend: React.js, Next.js, JavaScript, TypeScript, Tailwind CSS
- Backend: Node.js, Express.js, REST APIs
- Databases: MongoDB, PostgreSQL
## Official profiles
- [Upwork](https://www.upwork.com/freelancers/~0191c7eba12b27a044)
- [LinkedIn](https://www.linkedin.com/in/dhruv-sheladiya-a350582a6)
- [GitHub](https://github.com/Dhruv-1511)
β±οΈ Takes 5 minutes. There's no downside.
The Complete Checklist
- [ ] π View Page Source: is your name in the raw HTML?
- [ ] π§© JSONβLD Person with
sameAsfor all your profiles - [ ] π Every profile links back to your site
- [ ] πΌοΈ OG image is 1200×630 and under ~300β―KB
- [ ] π₯ Name first in
<title>, same headline everywhere - [ ] πΊοΈ Submit your sitemap to Google Search Console and Bing Webmaster Tools (ChatGPT search relies heavily on Bing!)
- [ ] π§ͺ Test with Google's Rich Results Test
- [ ] π€ Add an
/llms.txt
Final Thoughts
SEO for your own name is slow: expect a few weeks before things move. β³
But the best part? None of this required changing a single pixel of my UI. π¨β¨
Here's the live result π
π¨π» About Me
Hi, I'm Dhruv Sheladiya, a Full Stack Developer π building fast, scalable web apps & SaaS products with clean UI/UX, from frontend to backend.
| π Portfolio | aboutdhruv.vercel.app |
|---|---|
| πΌ Upwork | Hire me for freelance projects |
| π LinkedIn | Dhruv Sheladiya |
| π» GitHub | @Dhruv-1511 |
| π¦ X | @DhruvSheladiya2 |
| πΌ Hire Me on Upwork | π Visit My Portfolio |
Your turn
Open View Page Source on your portfolio right now. What did you find? Tell me in the comments π
β€οΈ If this helped, drop a reaction and follow me for more Next.js & React content!
Comments
No comments yet. Start the discussion.