SEO Doesn’t Have to Be Complicated (But It Does Have to Be Done Right)
Let me guess – you’ve built an amazing website, but nobody can find it on Google. Welcome to the club! I’ve been there, staring at Google Analytics showing zero organic traffic while wondering if search engines even knew my site existed.
Here’s the thing about SEO: everyone makes it sound way more complicated than it actually is. After building and optimizing sites with everything from Astro (like my portfolio at prakashraj.info) to Next.js apps (like The World Explorer), I’ve learned that good SEO comes down to a few core principles that work regardless of your tech stack.
I’m going to share the exact strategies that helped my sites consistently rank on the first page of Google. No fluff, no outdated tactics, just proven techniques that work in 2025.
Why You Should Actually Care About SEO
Before we dive into the technical stuff, let’s talk about why SEO should be at the top of your priority list:
Think about your own behavior online. When you search for something on Google, do you ever go to page 2? Probably not. You’re like 75% of people who never scroll past the first page of search results.
Here’s what blew my mind when I first learned these stats: 93% of all online experiences start with a search engine. That means almost everyone who could become your user, customer, or reader is going to find you through search – or they won’t find you at all.
The best part about SEO compared to paid ads? It’s like compound interest for your website. The work you do today keeps bringing traffic for years. I still get traffic from blog posts I wrote two years ago.
The SEO Basics That Work Everywhere
No matter what framework you’re using – Next.js, Astro, Vue, Svelte, or even plain HTML – these fundamentals are non-negotiable:
Core Web Vitals: The Speed Test That Matters
Google cares a lot about user experience, and Core Web Vitals are how they measure it. Think of them as Google’s report card for your site’s performance:
Largest Contentful Paint (LCP) – How fast does the main content load? (Should be under 2.5 seconds)
<!-- Make sure your hero image loads fast -->
<img src="hero.jpg" alt="Hero image" width="800" height="400" loading="eager" />
First Input Delay (FID) – How quickly can users interact with your page? (Should be under 100ms)
// Don't block the main thread with heavy code
setTimeout(() => {
// Put heavy computations here instead
}, 0);
Cumulative Layout Shift (CLS) – Does your page jump around while loading? (Should be under 0.1)
/* Always specify image dimensions to prevent layout jumps */
.hero-image {
width: 100%;
height: 400px;
object-fit: cover;
}
The Three Pillars of Technical SEO
Can Search Engines Find Your Pages? (Crawlability)
<!-- Your sitemap.xml helps search engines discover all your pages -->
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yoursite.com/</loc>
<lastmod>2025-09-06</lastmod>
<priority>1.0</priority>
</url>
</urlset>
Should Search Engines Show This Page? (Indexability)
<!-- Let search engines index this page -->
<meta name="robots" content="index, follow" />
<!-- Keep admin pages private -->
<meta name="robots" content="noindex, nofollow" />
Can Everyone Use Your Site? (Accessibility)
<!-- Semantic HTML helps both users and search engines understand your content -->
<main>
<article>
<header>
<h1>Your Main Heading</h1>
</header>
<section>
<h2>Section Heading</h2>
<p>Content goes here...</p>
</section>
</article>
</main>
How to Do This in Your Favorite Framework
Next.js: The SEO Powerhouse
Next.js makes SEO almost too easy. Here’s how to set it up right:
The New Metadata API (App Router)
This is the modern way to handle SEO in Next.js:
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Complete Guide to SEO | YourSite',
description: 'Learn proven SEO strategies that work across any modern web framework',
keywords: ['SEO', 'web development', 'Next.js', 'optimization'],
authors: [{ name: 'Prakash Raj' }],
openGraph: {
title: 'Complete Guide to SEO',
description: 'Proven SEO strategies for modern web frameworks',
url: 'https://yoursite.com/seo-guide',
siteName: 'YourSite',
images: [
{
url: 'https://yoursite.com/og-image.jpg',
width: 800,
height: 600,
},
],
locale: 'en_US',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'Complete Guide to SEO',
description: 'Proven SEO strategies for modern web frameworks',
images: ['https://yoursite.com/twitter-image.jpg'],
},
};
export default function SEOGuidePage() {
return (
<article>
<h1>The Complete Guide to SEO</h1>
{/* Your content */}
</article>
);
}
Dynamic SEO for Blog Posts
For content that changes (like blog posts), you can generate metadata dynamically:
interface PageProps {
params: { slug: string };
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const post = await fetchBlogPost(params.slug);
return {
title: `${post.title} | YourBlog`,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [post.image],
},
};
}
Rich Snippets with Structured Data
This is the code that tells Google “hey, this is a blog post” so you can get those fancy search results:
export default function BlogPost({ post }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
description: post.excerpt,
image: post.image,
author: {
'@type': 'Person',
name: 'Prakash Raj',
},
datePublished: post.publishedAt,
dateModified: post.updatedAt,
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article>
<h1>{post.title}</h1>
{/* Your post content */}
</article>
</>
);
}
Astro: SEO Made Simple
Astro is naturally great for SEO because it generates static HTML by default. Here’s how to make it even better:
1. Layout-Based SEO
---
// src/layouts/BaseLayout.astro
export interface Props {
title: string;
description: string;
image?: string;
canonicalURL?: string;
}
const { title, description, image, canonicalURL } = Astro.props;
const currentURL = new URL(Astro.request.url);
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<link rel="canonical" href={canonicalURL || currentURL} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={currentURL} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={currentURL} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={image} />
</head>
<body>
<slot />
</body>
</html>
2. Content Collections for Blog SEO
---
// src/pages/blog/[...slug].astro
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
export async function getStaticPaths() {
const blogPosts = await getCollection('blog');
return blogPosts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<BaseLayout
title={`${post.data.title} | Your Blog`}
description={post.data.description}
image={post.data.image}
>
<article>
<header>
<h1>{post.data.title}</h1>
<time datetime={post.data.publishedAt.toISOString()}>
{post.data.publishedAt.toLocaleDateString()}
</time>
</header>
<Content />
</article>
</BaseLayout>
Vue/Nuxt SEO Optimization
1. Nuxt SEO Module
<template>
<div>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
</div>
</template>
<script setup>
const { data: post } = await $fetch(`/api/posts/${route.params.slug}`);
// SEO Meta
useHead({
title: `${post.title} | YourSite`,
meta: [
{ name: 'description', content: post.excerpt },
{ property: 'og:title', content: post.title },
{ property: 'og:description', content: post.excerpt },
{ property: 'og:image', content: post.image },
],
});
// Structured data
useJsonld({
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
description: post.excerpt,
});
</script>
SvelteKit SEO Optimization
1. Dynamic Meta Tags
<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
import { page } from '$app/stores';
export let data;
$: seo = {
title: `${data.post.title} | YourBlog`,
description: data.post.excerpt,
url: $page.url.href,
image: data.post.image
};
</script>
<svelte:head>
<title>{seo.title}</title>
<meta name="description" content={seo.description} />
<meta property="og:title" content={seo.title} />
<meta property="og:description" content={seo.description} />
<meta property="og:url" content={seo.url} />
<meta property="og:image" content={seo.image} />
</svelte:head>
<article>
<h1>{data.post.title}</h1>
{@html data.post.content}
</article>
Content That Actually Ranks
Here’s the truth: all the technical SEO in the world won’t help if your content sucks. But good content with bad technical SEO also won’t rank. You need both.
Keyword Research That Works
Forget expensive tools for now. Start with these free ones:
- Google Keyword Planner – Shows you actual search volumes
- AnswerThePublic – Find questions people are asking
- Google Search Console – See what you already rank for
My strategy: Find a primary keyword (like “SEO optimization”), then build around related keywords (“technical SEO,” “website optimization,” “SEO tips”).
Content Structure That Google Loves
<h1>Main Topic (Your Primary Keyword)</h1>
<h2>Subtopic 1 (Related Keyword)</h2>
<h3>Specific Point</h3>
<h2>Subtopic 2 (Another Related Keyword)</h2>
<h3>Another Point</h3>
Content length that actually works:
- Blog posts: 1,500+ words (this post is over 4,000)
- Landing pages: 800+ words
- Product pages: 300+ words
Internal Linking (Don’t Skip This!)
Link to your other content with descriptive text:
<p>
Learn more about <a href="/blog/nextjs-performance">optimizing Next.js performance</a> or check
out our <a href="/blog/astro-guide">complete Astro tutorial</a>.
</p>
My rules:
- Link to 3-5 related pages per post
- Use descriptive anchor text (never “click here”)
- Link to both new and old content
- Create topic clusters around your main keywords
The Technical Stuff (Keep It Simple)
Sitemap: Help Google Find Everything
Create a sitemap.xml file that lists all your pages:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yoursite.com/</loc>
<lastmod>2025-09-06</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://yoursite.com/blog</loc>
<lastmod>2025-09-06</lastmod>
<priority>0.9</priority>
</url>
</urlset>
Robots.txt: Set the Rules
User-agent: *
Allow: /
# Block admin areas
Disallow: /admin/
Disallow: /private/
# Point to your sitemap
Sitemap: https://yoursite.com/sitemap.xml
Image Optimization (Super Important)
<!-- Always specify dimensions and use alt text -->
<img
src="hero.jpg"
alt="Descriptive text about the image"
width="800"
height="400"
loading="lazy"
/>
Tracking Your Success
Essential Tools (All Free)
- Google Search Console – See how you appear in search
- Google Analytics – Track your traffic
- PageSpeed Insights – Check your site speed
What to Actually Monitor
- Organic search traffic (going up?)
- Your keyword rankings (improving?)
- Site speed scores (above 90?)
- Any crawl errors (fix them quickly!)
Monthly SEO Checklist
- Check Google Search Console for errors
- Review your top-performing pages
- Update any outdated content
- Look for broken links
- Monitor your keyword rankings
Common SEO Mistakes (Learn from My Pain)
Don’t Do This
<!-- Missing alt text -->
<img src="product.jpg" />
<!-- Generic meta descriptions -->
<meta name="description" content="Welcome to our website" />
<!-- Keyword stuffing -->
<h1>SEO SEO SEO Best SEO Guide for SEO Optimization</h1>
Do This Instead
<!-- Descriptive alt text -->
<img src="product.jpg" alt="Red wireless headphones with noise cancellation" />
<!-- Compelling meta descriptions -->
<meta
name="description"
content="Learn proven SEO strategies that will help your website rank higher in search results. Complete guide with examples."
/>
<!-- Natural keyword usage -->
<h1>The Complete SEO Guide for Modern Websites</h1>
The Real Talk: What Actually Matters
After optimizing dozens of websites, here’s what I’ve learned:
Focus on these three things first:
- Make your site fast – Under 3 seconds load time
- Write helpful content – Answer real questions people have
- Get the basics right – Title tags, meta descriptions, heading structure
Framework doesn’t matter as much as you think. I’ve seen beautiful Next.js sites with terrible SEO get crushed by simple static sites that followed the basics.
SEO takes time. Don’t expect overnight results. Good SEO is a 3-6 month game, but it pays off for years.
Write for humans first. Google is getting really good at detecting when you’re writing just for search engines instead of actual people.
Want to See This in Action?
Check out how I implemented these strategies:
- My Astro Portfolio – Perfect performance scores
- Next.js App – Dynamic SEO done right
Both sites consistently rank on the first page for their target keywords using exactly these techniques.
Final Thoughts
SEO isn’t magic, and it’s not as complicated as everyone makes it seem. Focus on building a fast site with genuinely helpful content, get the technical basics right, and be patient.
The websites that win at SEO in 2025 are the ones that actually help people solve their problems. Everything else is just optimization around the edges.