👋 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.
Runcurl https://your-site.comor 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 👇
const jsonLd = { "@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 | 1200 × 630 |
| Weight | 1.77 MB | 80 KB |
| Format | PNG | 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:imageis 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 |
🤖 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.
# 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
PersonwithsameAsfor 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 |
| Dhruv Sheladiya | |
| 💻 GitHub | @Dhruv-1511 |
| 🐦 X | @DhruvSheladiya2 |
💬 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!