[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6HAMJDAY0MTZF356DBQCR0V":3,"skill-same:01M6HAMJDAY0MTZF356DBQCR0V":88},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":66,"commitSha":67,"skillDirectory":68,"forksCount":14,"repositoryHtmlUrl":69,"repositoryHomepageUrl":6,"ownerHtmlUrl":70,"ownerBlogUrl":71,"ownerDescription":72,"updatedAt":73,"install":74,"resources":87},"01M6HAMJDAY0MTZF356DBQCR0V","serverside-rendering",null,"Expert guidance on server-side rendering for improved performance and SEO. Use for:  React SSR with Next.js, Vue SSR with Nuxt, hydration strategies, server state management,  streaming SSR, edge rendering, caching strategies, SEO optimization, and building  performance-critical web applications.","NeuralBlitz\u002FMito","NeuralBlitz","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F79354388?v=4","01M6H8T2TFH477HRS0KTSTKR2E","David Riggs","01M6H8T2YQQDXPYM092P670Z21",0,"MIT","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fserverside-rendering\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000019","营销推广",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000035","市场营销","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"rendering","serverside rendering","expert","for","seo optimization","critical","server-side","strategies","caching","next","performance","opencode","seo","nextjs","server","vue","streaming","development","ssr","react","2026-11-10 10:12:30",false,"---\nname: serverside-rendering\ndescription: >\n  Expert guidance on server-side rendering for improved performance and SEO. Use for: \n  React SSR with Next.js, Vue SSR with Nuxt, hydration strategies, server state management, \n  streaming SSR, edge rendering, caching strategies, SEO optimization, and building \n  performance-critical web applications.\nlicense: MIT\ncompatibility: opencode\nmetadata:\n  audience: web-developers\n  category: web-development\n  tags: [ssr, nextjs, hydration, seo, rendering]\n---\n\n# Server-Side Rendering — Implementation Guide\n\nCovers: **Next.js SSR · Nuxt SSR · Hydration · Streaming · Edge Rendering · SEO Optimization · Caching**\n\n-----\n\n## Understanding SSR\n\n### How Server-Side Rendering Works\n\nServer-side rendering generates complete HTML pages on the server in response to client requests. Unlike client-side rendering where the browser builds the page after downloading JavaScript, SSR delivers ready-to-render HTML that improves perceived performance, enables better SEO, and provides optimal experience on slow devices.\n\nThe rendering process involves multiple steps: the server receives a request for a page, executes the application code to generate the component tree, fetches any required data from databases or APIs, renders the components to HTML, and sends the complete HTML document to the browser. The browser can display this HTML immediately while downloading and executing JavaScript for hydration.\n\n**Key Benefits:**\n\n- **Faster First Contentful Paint** — Users see content before JavaScript loads.\n- **Better SEO** — Search engines can crawl fully rendered content.\n- **Improved Performance on Slow Devices** — Less JavaScript processing on client.\n- **Social Media Previews** — Open Graph tags work reliably.\n\n**Trade-offs:**\n\n- **Increased Server Load** — Each request requires server rendering.\n- **Time to First Byte** — Server processing adds latency.\n- **Complex Caching** — Requires careful cache strategy.\n- **Hydration Cost** — Client must still process JavaScript.\n\n### SSR vs SSG vs ISR\n\n| Approach | When HTML Generated | Use Case |\n|----------|-------------------|----------|\n| **SSR** (Server-Side Rendering) | Request time | Dynamic, personalized content |\n| **SSG** (Static Site Generation) | Build time | Documentation, blogs, marketing |\n| **ISR** (Incremental Static Regeneration) | Request + background | Content that updates periodically |\n| **Edge Rendering** | Edge location | Global, low-latency content |\n\n-----\n\n## Next.js SSR\n\n### App Router (Next.js 13+)\n\n```javascript\n\u002F\u002F app\u002Fpage.tsx - Server Component by default\nimport { getData } from '@\u002Flib\u002Fapi';\n\nasync function getServerData() {\n  const res = await fetch('https:\u002F\u002Fapi.example.com\u002Fdata', {\n    \u002F\u002F Cache configuration\n    cache: 'no-store',  \u002F\u002F Don't cache, fetch fresh each time\n    \u002F\u002F or: cache: 'force-cache'  \u002F\u002F Static generation\n    \u002F\u002F or: next: { revalidate: 3600 }  \u002F\u002F ISR - revalidate every hour\n  });\n  \n  if (!res.ok) {\n    throw new Error('Failed to fetch data');\n  }\n  \n  return res.json();\n}\n\nexport default async function Page() {\n  \u002F\u002F This component runs on the server\n  const data = await getData();\n  \n  return (\n    \u003Cmain>\n      \u003Ch1>{data.title}\u003C\u002Fh1>\n      \u003Cp>{data.description}\u003C\u002Fp>\n      \u003Cul>\n        {data.items.map((item) => (\n          \u003Cli key={item.id}>{item.name}\u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    \u003C\u002Fmain>\n  );\n}\n```\n\n### Client Components with SSR\n\n```javascript\n\u002F\u002F app\u002Fcomponents\u002FCounter.tsx - Client Component\n'use client';\n\nimport { useState } from 'react';\n\nexport default function Counter({ initialCount = 0 }) {\n  const [count, setCount] = useState(initialCount);\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count}\u003C\u002Fp>\n      \u003Cbutton onClick={() => setCount(count + 1)}>\n        Increment\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F app\u002Fpage.tsx - Using client component in server component\nimport Counter from '.\u002Fcomponents\u002FCounter';\nimport { getInitialCount } from '@\u002Flib\u002Fapi';\n\nexport default async function Page() {\n  const initialCount = await getInitialCount();\n  \n  return (\n    \u003Cmain>\n      \u003Ch1>Server-Rendered Page\u003C\u002Fh1>\n      \u003CCounter initialCount={initialCount} \u002F>\n    \u003C\u002Fmain>\n  );\n}\n```\n\n### Data Fetching Patterns\n\n```javascript\n\u002F\u002F Parallel data fetching - fetch in parallel for performance\nimport { getUser, getPosts } from '@\u002Flib\u002Fapi';\n\nexport default async function Page() {\n  \u002F\u002F Start both fetches simultaneously\n  const userData = getUser();\n  const postsData = getPosts();\n  \n  \u002F\u002F Wait for both\n  const [user, posts] = await Promise.all([userData, postsData]);\n  \n  return (\n    \u003Cdiv>\n      \u003Ch1>{user.name}\u003C\u002Fh1>\n      \u003CPostsList posts={posts} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F Sequential fetching - when data depends on previous\nexport default async function Page() {\n  const user = await getCurrentUser();\n  \n  if (!user) {\n    redirect('\u002Flogin');\n  }\n  \n  const settings = await getUserSettings(user.id);\n  \n  return \u003CSettingsPage user={user} settings={settings} \u002F>;\n}\n\n\u002F\u002F Streaming with Suspense - show shell while loading\nimport { Suspense } from 'react';\n\nexport default function Page() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CSuspense fallback={\u003CPostsSkeleton \u002F>}>\n        \u003CPostsList \u002F>\n      \u003C\u002FSuspense>\n      \u003CSuspense fallback={\u003CCommentsSkeleton \u002F>}>\n        \u003CCommentsList \u002F>\n      \u003C\u002FSuspense>\n    \u003C\u002Fdiv>\n  );\n}\n\nasync function PostsList() {\n  const posts = await getPosts();\n  return \u003CPostCards posts={posts} \u002F>;\n}\n```\n\n### Route Handlers (API Routes)\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Fusers\u002Froute.ts\nimport { NextRequest, NextResponse } from 'next\u002Fserver';\n\nexport async function GET(request: NextRequest) {\n  const { searchParams } = new URL(request.url);\n  const page = searchParams.get('page') || '1';\n  const limit = searchParams.get('limit') || '10';\n  \n  const users = await fetchUsers(parseInt(page), parseInt(limit));\n  \n  return NextResponse.json(users);\n}\n\nexport async function POST(request: NextRequest) {\n  const body = await request.json();\n  \n  \u002F\u002F Validate\n  if (!body.email || !body.name) {\n    return NextResponse.json(\n      { error: 'Missing required fields' },\n      { status: 400 }\n    );\n  }\n  \n  const user = await createUser(body);\n  \n  return NextResponse.json(user, { status: 201 });\n}\n\n\u002F\u002F With caching\nexport async function GET() {\n  const data = await getExpensiveData();\n  \n  return NextResponse.json(data, {\n    headers: {\n      'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400'\n    }\n  });\n}\n```\n\n-----\n\n## Hydration Strategies\n\n### Understanding Hydration\n\nHydration is the process where client-side JavaScript takes over the server-rendered HTML, attaching event listeners and making the page interactive. Understanding hydration is crucial for optimizing performance, as poorly optimized hydration can lead to slow Time to Interactive (TTI).\n\n**Hydration Challenges:**\n\n- Large bundle sizes delay interactivity\n- Component trees with many nodes take time to hydrate\n- Third-party scripts compete for resources\n- Heavy computation during hydration blocks interaction\n\n### Partial Hydration\n\n```javascript\n\u002F\u002F Strategy 1: Lazy load non-critical components\nimport dynamic from 'next\u002Fdynamic';\n\nconst HeavyChart = dynamic(\n  () => import('.\u002FHeavyChart'),\n  { \n    loading: () => \u003CChartSkeleton \u002F>,\n    ssr: false  \u002F\u002F Don't render on server\n  }\n);\n\nexport default function Dashboard({ data }) {\n  return (\n    \u003Cdiv>\n      \u003CSummaryCards data={data} \u002F>\n      {\u002F* Chart loads after initial render *\u002F}\n      \u003CHeavyChart data={data.chartData} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F Strategy 2: use client boundary\n\u002F\u002F components\u002FInteractiveMap.tsx\n'use client';\n\nimport { useState, useEffect } from 'react';\n\nexport default function InteractiveMap({ markers }) {\n  const [map, setMap] = useState(null);\n  \n  useEffect(() => {\n    \u002F\u002F Load map library only on client\n    initMap().then(setMap);\n  }, []);\n  \n  return \u003Cdiv id=\"map\" \u002F>;\n}\n\n\u002F\u002F Only hydrate the interactive part\n```\n\n### Selective Hydration\n\n```javascript\n\u002F\u002F components\u002FCommentSection.tsx\n'use client';\n\nimport { useState } from 'react';\n\nexport default function CommentSection({ initialComments }) {\n  const [comments, setComments] = useState(initialComments);\n  \n  \u002F\u002F Only interactive parts hydrate\n  return (\n    \u003Cdiv>\n      {comments.map(comment => (\n        \u003CComment key={comment.id} data={comment} \u002F>\n      ))}\n      \n      \u003CAddCommentForm onSubmit={addComment} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F components\u002FComment.tsx - Can stay static if no interactivity\nexport default function Comment({ data }) {\n  \u002F\u002F Static display - no client JS needed\n  return (\n    \u003Carticle>\n      \u003Cstrong>{data.author}\u003C\u002Fstrong>\n      \u003Cp>{data.text}\u003C\u002Fp>\n    \u003C\u002Farticle>\n  );\n}\n```\n\n### Hydration Error Handling\n\n```javascript\n\u002F\u002F lib\u002Fhydration-manager.tsx\n'use client';\n\nimport { useState, useEffect } from 'react';\n\nexport function useHydrated() {\n  const [hydrated, setHydrated] = useState(false);\n  \n  useEffect(() => {\n    setHydrated(true);\n  }, []);\n  \n  return hydrated;\n}\n\nexport function ClientOnly({ children, fallback = null }) {\n  const hydrated = useHydrated();\n  \n  return hydrated ? children : fallback;\n}\n\n\u002F\u002F Usage\nimport { ClientOnly } from '@\u002Flib\u002Fhydration-manager';\n\nexport default function Page() {\n  return (\n    \u003Cdiv>\n      \u003CServerRenderedContent \u002F>\n      \n      \u003CClientOnly fallback={\u003CSkeleton \u002F>}>\n        \u003CClientSideOnlyComponent \u002F>\n      \u003C\u002FClientOnly>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n-----\n\n## Streaming and Suspense\n\n### Streaming SSR\n\n```javascript\n\u002F\u002F Enable streaming in Next.js (default in App Router)\n\u002F\u002F Just use Suspense boundaries\n\nimport { Suspense } from 'react';\n\nexport default function Page() {\n  return (\n    \u003Cdiv className=\"layout\">\n      \u003CHeader \u002F>  {\u002F* Immediate render *\u002F}\n      \n      \u003CSuspense fallback={\u003CFeedSkeleton \u002F>}>\n        \u003CFeed \u002F>  {\u002F* Streams in when ready *\u002F}\n      \u003C\u002FSuspense>\n      \n      \u003CSuspense fallback={\u003CSidebarSkeleton \u002F>}>\n        \u003CSidebar \u002F>  {\u002F* Independent stream *\u002F}\n      \u003C\u002FSuspense>\n      \n      \u003CFooter \u002F>  {\u002F* Immediate render *\u002F}\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F components\u002FFeed.tsx\nasync function Feed() {\n  const posts = await getPosts();\n  \n  return (\n    \u003Cul>\n      {posts.map(post => (\n        \u003CPostCard key={post.id} post={post} \u002F>\n      ))}\n    \u003C\u002Ful>\n  );\n}\n```\n\n### Suspense with Error Boundaries\n\n```javascript\n\u002F\u002F components\u002FErrorBoundary.tsx\n'use client';\n\nimport { Component, ReactNode } from 'react';\n\ninterface Props {\n  children: ReactNode;\n  fallback: ReactNode;\n}\n\ninterface State {\n  hasError: boolean;\n  error?: Error;\n}\n\nclass ErrorBoundary extends Component\u003CProps, State> {\n  constructor(props: Props) {\n    super(props);\n    this.state = { hasError: false };\n  }\n  \n  static getDerivedStateFromError(error: Error): State {\n    return { hasError: true, error };\n  }\n  \n  componentDidCatch(error: Error, errorInfo: any) {\n    console.error('Error in component:', error, errorInfo);\n  }\n  \n  render() {\n    if (this.state.hasError) {\n      return this.props.fallback;\n    }\n    \n    return this.props.children;\n  }\n}\n\n\u002F\u002F Usage with Suspense\nexport default function Page() {\n  return (\n    \u003CErrorBoundary fallback={\u003CErrorPage \u002F>}>\n      \u003CSuspense fallback={\u003CLoading \u002F>}>\n        \u003CContent \u002F>\n      \u003C\u002FSuspense>\n    \u003C\u002FErrorBoundary>\n  );\n}\n```\n\n-----\n\n## Edge Rendering\n\n### Edge Functions\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Fhello\u002Froute.ts\nexport const runtime = 'edge';\n\nexport async function GET(request: Request) {\n  return new Response('Hello from the edge!', {\n    headers: { 'content-type': 'text\u002Fplain' }\n  });\n}\n\n\u002F\u002F Edge middleware\n\u002F\u002F middleware.ts\nimport { NextResponse } from 'next\u002Fserver';\nimport type { NextRequest } from 'next\u002Fserver';\n\nexport function middleware(request: NextRequest) {\n  \u002F\u002F Geo-based routing\n  const country = request.geo?.country || 'US';\n  \n  if (country === 'DE') {\n    return NextResponse.redirect(new URL('\u002Fde', request.url));\n  }\n  \n  \u002F\u002F A\u002FB testing\n  const bucket = Math.random() \u003C 0.5 ? 'a' : 'b';\n  const response = NextResponse.next();\n  response.cookies.set('ab-test', bucket);\n  \n  return response;\n}\n\nexport const config = {\n  matcher: '\u002F:path*',\n};\n```\n\n### Edge Caching Strategies\n\n```javascript\n\u002F\u002F app\u002Fproducts\u002F[id]\u002Fpage.tsx\nexport const runtime = 'edge';\nexport const dynamic = 'force-dynamic';\n\nexport default async function ProductPage({ params }) {\n  const product = await getProduct(params.id);\n  \n  return \u003CProductDetails product={product} \u002F>;\n}\n\n\u002F\u002F For static content with edge caching\nexport async function generateStaticParams() {\n  const products = await getAllProducts();\n  \n  return products.map((product) => ({\n    id: product.id,\n  }));\n}\n\nexport const revalidate = 3600;  \u002F\u002F Revalidate at edge every hour\n```\n\n-----\n\n## Caching Strategies\n\n### Route Cache Configuration\n\n```javascript\n\u002F\u002F app\u002Fblog\u002F[slug]\u002Fpage.tsx\n\n\u002F\u002F Static generation at build time\nexport async function generateStaticParams() {\n  const posts = await getAllPosts();\n  return posts.map((post) => ({\n    slug: post.slug,\n  }));\n}\n\n\u002F\u002F ISR - revalidate every hour\nexport const revalidate = 3600;\n\nexport default async function BlogPost({ params }) {\n  const post = await getPost(params.slug);\n  \n  return \u003CArticle post={post} \u002F>;\n}\n\n\u002F\u002F Cache tags for on-demand revalidation\nexport default async function ProductPage({ params }) {\n  const product = await getProduct(params.id);\n  \n  return \u003CProduct product={product} \u002F>;\n}\n\nexport async function generateStaticParams() {\n  const products = await getAllProducts();\n  return products.map((p) => ({ id: p.id }));\n}\n\n\u002F\u002F Using fetch cache options\nconst res = await fetch(`https:\u002F\u002Fapi.example.com\u002Fproducts\u002F${params.id}`, {\n  next: {\n    revalidate: 60,  \u002F\u002F Cache for 60 seconds\n    tags: ['products'],  \u002F\u002F For on-demand invalidation\n  },\n});\n```\n\n### On-Demand Revalidation\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Frevalidate\u002Froute.ts\nimport { NextRequest, NextResponse } from 'next\u002Fserver';\nimport { revalidateTag, revalidatePath } from 'next\u002Fcache';\n\nexport async function POST(request: NextRequest) {\n  const secret = request.nextUrl.searchParams.get('secret');\n  \n  \u002F\u002F Verify secret token\n  if (secret !== process.env.REVALIDATION_SECRET) {\n    return NextResponse.json({ message: 'Invalid token' }, { status: 401 });\n  }\n  \n  const body = await request.json();\n  const { tag, path } = body;\n  \n  if (tag) {\n    revalidateTag(tag);\n    return NextResponse.json({ revalidated: true, tag });\n  }\n  \n  if (path) {\n    revalidatePath(path);\n    return NextResponse.json({ revalidated: true, path });\n  }\n  \n  return NextResponse.json({ message: 'Missing tag or path' }, { status: 400 });\n}\n\n\u002F\u002F Webhook handler for CMS updates\n\u002F\u002F app\u002Fapi\u002Fcms-webhook\u002Froute.ts\nexport async function POST(request: NextRequest) {\n  const body = await request.json();\n  \n  if (body.type === 'post_updated') {\n    revalidateTag('posts');\n    revalidatePath('\u002Fblog');\n  }\n  \n  return NextResponse.json({ received: true });\n}\n```\n\n-----\n\n## SEO Optimization\n\n### Metadata API\n\n```javascript\n\u002F\u002F app\u002Flayout.tsx\nimport { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n  title: {\n    default: 'My Awesome Site',\n    template: '%s | My Awesome Site',\n  },\n  description: 'Description of my awesome website',\n  openGraph: {\n    title: 'My Awesome Site',\n    description: 'Description of my awesome website',\n    url: 'https:\u002F\u002Fmyawesomesite.com',\n    siteName: 'My Awesome Site',\n    images: [\n      {\n        url: 'https:\u002F\u002Fmyawesomesite.com\u002Fog-image.jpg',\n        width: 1200,\n        height: 630,\n      },\n    ],\n    locale: 'en_US',\n    type: 'website',\n  },\n  twitter: {\n    card: 'summary_large_image',\n    title: 'My Awesome Site',\n    creator: '@username',\n  },\n  robots: {\n    index: true,\n    follow: true,\n  },\n};\n\n\u002F\u002F Dynamic metadata\nexport async function generateMetadata({ params }): Promise\u003CMetadata> {\n  const product = await getProduct(params.id);\n  \n  return {\n    title: product.name,\n    description: product.description,\n    openGraph: {\n      images: [product.image],\n    },\n  };\n}\n```\n\n### Structured Data\n\n```javascript\n\u002F\u002F components\u002FProductSchema.tsx\nexport function ProductSchema({ product }) {\n  const schema = {\n    '@context': 'https:\u002F\u002Fschema.org',\n    '@type': 'Product',\n    name: product.name,\n    description: product.description,\n    image: product.images,\n    offers: {\n      '@type': 'Offer',\n      price: product.price,\n      priceCurrency: product.currency,\n      availability: product.inStock \n        ? 'https:\u002F\u002Fschema.org\u002FInStock' \n        : 'https:\u002F\u002Fschema.org\u002FOutOfStock',\n    },\n    aggregateRating: product.rating ? {\n      '@type': 'AggregateRating',\n      ratingValue: product.rating.value,\n      reviewCount: product.rating.count,\n    } : undefined,\n  };\n  \n  return (\n    \u003Cscript\n      type=\"application\u002Fld+json\"\n      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n    \u002F>\n  );\n}\n\n\u002F\u002F JSON-LD for organization\nexport function OrganizationSchema() {\n  const schema = {\n    '@context': 'https:\u002F\u002Fschema.org',\n    '@type': 'Organization',\n    name: 'Company Name',\n    url: 'https:\u002F\u002Fcompany.com',\n    logo: 'https:\u002F\u002Fcompany.com\u002Flogo.png',\n    contactPoint: {\n      '@type': 'ContactPoint',\n      telephone: '+1-555-555-5555',\n      contactType: 'customer service',\n    },\n  };\n  \n  return (\n    \u003Cscript\n      type=\"application\u002Fld+json\"\n      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n    \u002F>\n  );\n}\n```\n\n### Sitemap Generation\n\n```javascript\n\u002F\u002F app\u002Fsitemap.ts\nimport { MetadataRoute } from 'next';\n\nexport default async function sitemap(): Promise\u003CMetadataRoute.Sitemap> {\n  const baseUrl = 'https:\u002F\u002Fmyawesomesite.com';\n  \n  \u002F\u002F Fetch dynamic content\n  const posts = await getAllPosts();\n  const products = await getAllProducts();\n  \n  const staticPages = [\n    '',\n    '\u002Fabout',\n    '\u002Fcontact',\n    '\u002Fpricing',\n  ].map((route) => ({\n    url: `${baseUrl}${route}`,\n    lastModified: new Date(),\n    changeFrequency: 'monthly' as const,\n    priority: route === '' ? 1 : 0.8,\n  }));\n  \n  const blogPosts = posts.map((post) => ({\n    url: `${baseUrl}\u002Fblog\u002F${post.slug}`,\n    lastModified: new Date(post.updatedAt),\n    changeFrequency: 'weekly' as const,\n    priority: 0.7,\n  }));\n  \n  const productPages = products.map((product) => ({\n    url: `${baseUrl}\u002Fproducts\u002F${product.id}`,\n    lastModified: new Date(product.updatedAt),\n    changeFrequency: 'daily' as const,\n    priority: 0.9,\n  }));\n  \n  return [...staticPages, ...blogPosts, ...productPages];\n}\n```\n\n-----\n\n## Performance Optimization\n\n### Bundle Analysis\n\n```javascript\n\u002F\u002F next.config.js\nconst withBundleAnalyzer = require('@next\u002Fbundle-analyzer')({\n  enabled: process.env.ANALYZE === 'true',\n});\n\nmodule.exports = withBundleAnalyzer({\n  experimental: {\n    optimizePackageImports: ['lodash', 'moment', 'antd'],\n  },\n  webpack: (config, { isServer }) => {\n    \u002F\u002F Optimize third-party imports\n    if (!isServer) {\n      config.resolve.fallback = {\n        ...config.resolve.fallback,\n        fs: false,\n        net: false,\n        tls: false,\n      };\n    }\n    return config;\n  },\n});\n```\n\n### Font Optimization\n\n```javascript\n\u002F\u002F app\u002Flayout.tsx\nimport { Inter, JetBrains_Mono } from 'next\u002Ffont\u002Fgoogle';\n\nconst inter = Inter({\n  subsets: ['latin'],\n  display: 'swap',\n  variable: '--font-inter',\n});\n\nconst jetbrainsMono = JetBrains_Mono({\n  subsets: ['latin'],\n  display: 'swap',\n  variable: '--font-mono',\n});\n\nexport default function RootLayout({ children }) {\n  return (\n    \u003Chtml lang=\"en\" className={`${inter.variable} ${jetbrainsMono.variable}`}>\n      \u003Cbody>{children}\u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  );\n}\n```\n\n### Image Optimization\n\n```javascript\n\u002F\u002F components\u002FOptimizedImage.tsx\nimport Image from 'next\u002Fimage';\n\nexport function ProductImage({ src, alt, priority = false }) {\n  return (\n    \u003CImage\n      src={src}\n      alt={alt}\n      width={600}\n      height={400}\n      sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\"\n      priority={priority}\n      placeholder=\"blur\"\n      blurDataURL={generateBlurPlaceholder(src)}\n    \u002F>\n  );\n}\n\n\u002F\u002F Use responsive sizes properly\nexport function Gallery({ images }) {\n  return (\n    \u003Cdiv className=\"gallery\">\n      {images.map((img) => (\n        \u003CImage\n          key={img.id}\n          src={img.src}\n          alt={img.alt}\n          fill\n          sizes=\"(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw\"\n          style={{ objectFit: 'cover' }}\n        \u002F>\n      ))}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n-----\n\n## Best Practices\n\n1. **Default to Server Components** — Only use client components when necessary for interactivity.\n\n2. **Minimize Client Bundle** — Import server-only modules at the top level.\n\n3. **Use Streaming Strategically** — Wrap slow data fetches in Suspense boundaries.\n\n4. **Implement Proper Caching** — Use appropriate cache strategies for each data type.\n\n5. **Optimize Images and Fonts** — Use Next.js built-in optimizations.\n\n6. **Monitor Core Web Vitals** — Track LCP, FID, and CLS in production.\n\n7. **Use Edge Functions Judiciously** — They're fast but have limits on computation.\n\n8. **Plan for Incremental Migration** — You don't need to convert everything at once.\n","# Server-Side Rendering — Implementation Guide\n\nCovers: **Next.js SSR · Nuxt SSR · Hydration · Streaming · Edge Rendering · SEO Optimization · Caching**\n\n-----\n\n## Understanding SSR\n\n### How Server-Side Rendering Works\n\nServer-side rendering generates complete HTML pages on the server in response to client requests. Unlike client-side rendering where the browser builds the page after downloading JavaScript, SSR delivers ready-to-render HTML that improves perceived performance, enables better SEO, and provides optimal experience on slow devices.\n\nThe rendering process involves multiple steps: the server receives a request for a page, executes the application code to generate the component tree, fetches any required data from databases or APIs, renders the components to HTML, and sends the complete HTML document to the browser. The browser can display this HTML immediately while downloading and executing JavaScript for hydration.\n\n**Key Benefits:**\n\n- **Faster First Contentful Paint** — Users see content before JavaScript loads.\n- **Better SEO** — Search engines can crawl fully rendered content.\n- **Improved Performance on Slow Devices** — Less JavaScript processing on client.\n- **Social Media Previews** — Open Graph tags work reliably.\n\n**Trade-offs:**\n\n- **Increased Server Load** — Each request requires server rendering.\n- **Time to First Byte** — Server processing adds latency.\n- **Complex Caching** — Requires careful cache strategy.\n- **Hydration Cost** — Client must still process JavaScript.\n\n### SSR vs SSG vs ISR\n\n| Approach | When HTML Generated | Use Case |\n|----------|-------------------|----------|\n| **SSR** (Server-Side Rendering) | Request time | Dynamic, personalized content |\n| **SSG** (Static Site Generation) | Build time | Documentation, blogs, marketing |\n| **ISR** (Incremental Static Regeneration) | Request + background | Content that updates periodically |\n| **Edge Rendering** | Edge location | Global, low-latency content |\n\n-----\n\n## Next.js SSR\n\n### App Router (Next.js 13+)\n\n```javascript\n\u002F\u002F app\u002Fpage.tsx - Server Component by default\nimport { getData } from '@\u002Flib\u002Fapi';\n\nasync function getServerData() {\n  const res = await fetch('https:\u002F\u002Fapi.example.com\u002Fdata', {\n    \u002F\u002F Cache configuration\n    cache: 'no-store',  \u002F\u002F Don't cache, fetch fresh each time\n    \u002F\u002F or: cache: 'force-cache'  \u002F\u002F Static generation\n    \u002F\u002F or: next: { revalidate: 3600 }  \u002F\u002F ISR - revalidate every hour\n  });\n  \n  if (!res.ok) {\n    throw new Error('Failed to fetch data');\n  }\n  \n  return res.json();\n}\n\nexport default async function Page() {\n  \u002F\u002F This component runs on the server\n  const data = await getData();\n  \n  return (\n    \u003Cmain>\n      \u003Ch1>{data.title}\u003C\u002Fh1>\n      \u003Cp>{data.description}\u003C\u002Fp>\n      \u003Cul>\n        {data.items.map((item) => (\n          \u003Cli key={item.id}>{item.name}\u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    \u003C\u002Fmain>\n  );\n}\n```\n\n### Client Components with SSR\n\n```javascript\n\u002F\u002F app\u002Fcomponents\u002FCounter.tsx - Client Component\n'use client';\n\nimport { useState } from 'react';\n\nexport default function Counter({ initialCount = 0 }) {\n  const [count, setCount] = useState(initialCount);\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count}\u003C\u002Fp>\n      \u003Cbutton onClick={() => setCount(count + 1)}>\n        Increment\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F app\u002Fpage.tsx - Using client component in server component\nimport Counter from '.\u002Fcomponents\u002FCounter';\nimport { getInitialCount } from '@\u002Flib\u002Fapi';\n\nexport default async function Page() {\n  const initialCount = await getInitialCount();\n  \n  return (\n    \u003Cmain>\n      \u003Ch1>Server-Rendered Page\u003C\u002Fh1>\n      \u003CCounter initialCount={initialCount} \u002F>\n    \u003C\u002Fmain>\n  );\n}\n```\n\n### Data Fetching Patterns\n\n```javascript\n\u002F\u002F Parallel data fetching - fetch in parallel for performance\nimport { getUser, getPosts } from '@\u002Flib\u002Fapi';\n\nexport default async function Page() {\n  \u002F\u002F Start both fetches simultaneously\n  const userData = getUser();\n  const postsData = getPosts();\n  \n  \u002F\u002F Wait for both\n  const [user, posts] = await Promise.all([userData, postsData]);\n  \n  return (\n    \u003Cdiv>\n      \u003Ch1>{user.name}\u003C\u002Fh1>\n      \u003CPostsList posts={posts} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F Sequential fetching - when data depends on previous\nexport default async function Page() {\n  const user = await getCurrentUser();\n  \n  if (!user) {\n    redirect('\u002Flogin');\n  }\n  \n  const settings = await getUserSettings(user.id);\n  \n  return \u003CSettingsPage user={user} settings={settings} \u002F>;\n}\n\n\u002F\u002F Streaming with Suspense - show shell while loading\nimport { Suspense } from 'react';\n\nexport default function Page() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CSuspense fallback={\u003CPostsSkeleton \u002F>}>\n        \u003CPostsList \u002F>\n      \u003C\u002FSuspense>\n      \u003CSuspense fallback={\u003CCommentsSkeleton \u002F>}>\n        \u003CCommentsList \u002F>\n      \u003C\u002FSuspense>\n    \u003C\u002Fdiv>\n  );\n}\n\nasync function PostsList() {\n  const posts = await getPosts();\n  return \u003CPostCards posts={posts} \u002F>;\n}\n```\n\n### Route Handlers (API Routes)\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Fusers\u002Froute.ts\nimport { NextRequest, NextResponse } from 'next\u002Fserver';\n\nexport async function GET(request: NextRequest) {\n  const { searchParams } = new URL(request.url);\n  const page = searchParams.get('page') || '1';\n  const limit = searchParams.get('limit') || '10';\n  \n  const users = await fetchUsers(parseInt(page), parseInt(limit));\n  \n  return NextResponse.json(users);\n}\n\nexport async function POST(request: NextRequest) {\n  const body = await request.json();\n  \n  \u002F\u002F Validate\n  if (!body.email || !body.name) {\n    return NextResponse.json(\n      { error: 'Missing required fields' },\n      { status: 400 }\n    );\n  }\n  \n  const user = await createUser(body);\n  \n  return NextResponse.json(user, { status: 201 });\n}\n\n\u002F\u002F With caching\nexport async function GET() {\n  const data = await getExpensiveData();\n  \n  return NextResponse.json(data, {\n    headers: {\n      'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400'\n    }\n  });\n}\n```\n\n-----\n\n## Hydration Strategies\n\n### Understanding Hydration\n\nHydration is the process where client-side JavaScript takes over the server-rendered HTML, attaching event listeners and making the page interactive. Understanding hydration is crucial for optimizing performance, as poorly optimized hydration can lead to slow Time to Interactive (TTI).\n\n**Hydration Challenges:**\n\n- Large bundle sizes delay interactivity\n- Component trees with many nodes take time to hydrate\n- Third-party scripts compete for resources\n- Heavy computation during hydration blocks interaction\n\n### Partial Hydration\n\n```javascript\n\u002F\u002F Strategy 1: Lazy load non-critical components\nimport dynamic from 'next\u002Fdynamic';\n\nconst HeavyChart = dynamic(\n  () => import('.\u002FHeavyChart'),\n  { \n    loading: () => \u003CChartSkeleton \u002F>,\n    ssr: false  \u002F\u002F Don't render on server\n  }\n);\n\nexport default function Dashboard({ data }) {\n  return (\n    \u003Cdiv>\n      \u003CSummaryCards data={data} \u002F>\n      {\u002F* Chart loads after initial render *\u002F}\n      \u003CHeavyChart data={data.chartData} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F Strategy 2: use client boundary\n\u002F\u002F components\u002FInteractiveMap.tsx\n'use client';\n\nimport { useState, useEffect } from 'react';\n\nexport default function InteractiveMap({ markers }) {\n  const [map, setMap] = useState(null);\n  \n  useEffect(() => {\n    \u002F\u002F Load map library only on client\n    initMap().then(setMap);\n  }, []);\n  \n  return \u003Cdiv id=\"map\" \u002F>;\n}\n\n\u002F\u002F Only hydrate the interactive part\n```\n\n### Selective Hydration\n\n```javascript\n\u002F\u002F components\u002FCommentSection.tsx\n'use client';\n\nimport { useState } from 'react';\n\nexport default function CommentSection({ initialComments }) {\n  const [comments, setComments] = useState(initialComments);\n  \n  \u002F\u002F Only interactive parts hydrate\n  return (\n    \u003Cdiv>\n      {comments.map(comment => (\n        \u003CComment key={comment.id} data={comment} \u002F>\n      ))}\n      \n      \u003CAddCommentForm onSubmit={addComment} \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F components\u002FComment.tsx - Can stay static if no interactivity\nexport default function Comment({ data }) {\n  \u002F\u002F Static display - no client JS needed\n  return (\n    \u003Carticle>\n      \u003Cstrong>{data.author}\u003C\u002Fstrong>\n      \u003Cp>{data.text}\u003C\u002Fp>\n    \u003C\u002Farticle>\n  );\n}\n```\n\n### Hydration Error Handling\n\n```javascript\n\u002F\u002F lib\u002Fhydration-manager.tsx\n'use client';\n\nimport { useState, useEffect } from 'react';\n\nexport function useHydrated() {\n  const [hydrated, setHydrated] = useState(false);\n  \n  useEffect(() => {\n    setHydrated(true);\n  }, []);\n  \n  return hydrated;\n}\n\nexport function ClientOnly({ children, fallback = null }) {\n  const hydrated = useHydrated();\n  \n  return hydrated ? children : fallback;\n}\n\n\u002F\u002F Usage\nimport { ClientOnly } from '@\u002Flib\u002Fhydration-manager';\n\nexport default function Page() {\n  return (\n    \u003Cdiv>\n      \u003CServerRenderedContent \u002F>\n      \n      \u003CClientOnly fallback={\u003CSkeleton \u002F>}>\n        \u003CClientSideOnlyComponent \u002F>\n      \u003C\u002FClientOnly>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n-----\n\n## Streaming and Suspense\n\n### Streaming SSR\n\n```javascript\n\u002F\u002F Enable streaming in Next.js (default in App Router)\n\u002F\u002F Just use Suspense boundaries\n\nimport { Suspense } from 'react';\n\nexport default function Page() {\n  return (\n    \u003Cdiv className=\"layout\">\n      \u003CHeader \u002F>  {\u002F* Immediate render *\u002F}\n      \n      \u003CSuspense fallback={\u003CFeedSkeleton \u002F>}>\n        \u003CFeed \u002F>  {\u002F* Streams in when ready *\u002F}\n      \u003C\u002FSuspense>\n      \n      \u003CSuspense fallback={\u003CSidebarSkeleton \u002F>}>\n        \u003CSidebar \u002F>  {\u002F* Independent stream *\u002F}\n      \u003C\u002FSuspense>\n      \n      \u003CFooter \u002F>  {\u002F* Immediate render *\u002F}\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F components\u002FFeed.tsx\nasync function Feed() {\n  const posts = await getPosts();\n  \n  return (\n    \u003Cul>\n      {posts.map(post => (\n        \u003CPostCard key={post.id} post={post} \u002F>\n      ))}\n    \u003C\u002Ful>\n  );\n}\n```\n\n### Suspense with Error Boundaries\n\n```javascript\n\u002F\u002F components\u002FErrorBoundary.tsx\n'use client';\n\nimport { Component, ReactNode } from 'react';\n\ninterface Props {\n  children: ReactNode;\n  fallback: ReactNode;\n}\n\ninterface State {\n  hasError: boolean;\n  error?: Error;\n}\n\nclass ErrorBoundary extends Component\u003CProps, State> {\n  constructor(props: Props) {\n    super(props);\n    this.state = { hasError: false };\n  }\n  \n  static getDerivedStateFromError(error: Error): State {\n    return { hasError: true, error };\n  }\n  \n  componentDidCatch(error: Error, errorInfo: any) {\n    console.error('Error in component:', error, errorInfo);\n  }\n  \n  render() {\n    if (this.state.hasError) {\n      return this.props.fallback;\n    }\n    \n    return this.props.children;\n  }\n}\n\n\u002F\u002F Usage with Suspense\nexport default function Page() {\n  return (\n    \u003CErrorBoundary fallback={\u003CErrorPage \u002F>}>\n      \u003CSuspense fallback={\u003CLoading \u002F>}>\n        \u003CContent \u002F>\n      \u003C\u002FSuspense>\n    \u003C\u002FErrorBoundary>\n  );\n}\n```\n\n-----\n\n## Edge Rendering\n\n### Edge Functions\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Fhello\u002Froute.ts\nexport const runtime = 'edge';\n\nexport async function GET(request: Request) {\n  return new Response('Hello from the edge!', {\n    headers: { 'content-type': 'text\u002Fplain' }\n  });\n}\n\n\u002F\u002F Edge middleware\n\u002F\u002F middleware.ts\nimport { NextResponse } from 'next\u002Fserver';\nimport type { NextRequest } from 'next\u002Fserver';\n\nexport function middleware(request: NextRequest) {\n  \u002F\u002F Geo-based routing\n  const country = request.geo?.country || 'US';\n  \n  if (country === 'DE') {\n    return NextResponse.redirect(new URL('\u002Fde', request.url));\n  }\n  \n  \u002F\u002F A\u002FB testing\n  const bucket = Math.random() \u003C 0.5 ? 'a' : 'b';\n  const response = NextResponse.next();\n  response.cookies.set('ab-test', bucket);\n  \n  return response;\n}\n\nexport const config = {\n  matcher: '\u002F:path*',\n};\n```\n\n### Edge Caching Strategies\n\n```javascript\n\u002F\u002F app\u002Fproducts\u002F[id]\u002Fpage.tsx\nexport const runtime = 'edge';\nexport const dynamic = 'force-dynamic';\n\nexport default async function ProductPage({ params }) {\n  const product = await getProduct(params.id);\n  \n  return \u003CProductDetails product={product} \u002F>;\n}\n\n\u002F\u002F For static content with edge caching\nexport async function generateStaticParams() {\n  const products = await getAllProducts();\n  \n  return products.map((product) => ({\n    id: product.id,\n  }));\n}\n\nexport const revalidate = 3600;  \u002F\u002F Revalidate at edge every hour\n```\n\n-----\n\n## Caching Strategies\n\n### Route Cache Configuration\n\n```javascript\n\u002F\u002F app\u002Fblog\u002F[slug]\u002Fpage.tsx\n\n\u002F\u002F Static generation at build time\nexport async function generateStaticParams() {\n  const posts = await getAllPosts();\n  return posts.map((post) => ({\n    slug: post.slug,\n  }));\n}\n\n\u002F\u002F ISR - revalidate every hour\nexport const revalidate = 3600;\n\nexport default async function BlogPost({ params }) {\n  const post = await getPost(params.slug);\n  \n  return \u003CArticle post={post} \u002F>;\n}\n\n\u002F\u002F Cache tags for on-demand revalidation\nexport default async function ProductPage({ params }) {\n  const product = await getProduct(params.id);\n  \n  return \u003CProduct product={product} \u002F>;\n}\n\nexport async function generateStaticParams() {\n  const products = await getAllProducts();\n  return products.map((p) => ({ id: p.id }));\n}\n\n\u002F\u002F Using fetch cache options\nconst res = await fetch(`https:\u002F\u002Fapi.example.com\u002Fproducts\u002F${params.id}`, {\n  next: {\n    revalidate: 60,  \u002F\u002F Cache for 60 seconds\n    tags: ['products'],  \u002F\u002F For on-demand invalidation\n  },\n});\n```\n\n### On-Demand Revalidation\n\n```javascript\n\u002F\u002F app\u002Fapi\u002Frevalidate\u002Froute.ts\nimport { NextRequest, NextResponse } from 'next\u002Fserver';\nimport { revalidateTag, revalidatePath } from 'next\u002Fcache';\n\nexport async function POST(request: NextRequest) {\n  const secret = request.nextUrl.searchParams.get('secret');\n  \n  \u002F\u002F Verify secret token\n  if (secret !== process.env.REVALIDATION_SECRET) {\n    return NextResponse.json({ message: 'Invalid token' }, { status: 401 });\n  }\n  \n  const body = await request.json();\n  const { tag, path } = body;\n  \n  if (tag) {\n    revalidateTag(tag);\n    return NextResponse.json({ revalidated: true, tag });\n  }\n  \n  if (path) {\n    revalidatePath(path);\n    return NextResponse.json({ revalidated: true, path });\n  }\n  \n  return NextResponse.json({ message: 'Missing tag or path' }, { status: 400 });\n}\n\n\u002F\u002F Webhook handler for CMS updates\n\u002F\u002F app\u002Fapi\u002Fcms-webhook\u002Froute.ts\nexport async function POST(request: NextRequest) {\n  const body = await request.json();\n  \n  if (body.type === 'post_updated') {\n    revalidateTag('posts');\n    revalidatePath('\u002Fblog');\n  }\n  \n  return NextResponse.json({ received: true });\n}\n```\n\n-----\n\n## SEO Optimization\n\n### Metadata API\n\n```javascript\n\u002F\u002F app\u002Flayout.tsx\nimport { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n  title: {\n    default: 'My Awesome Site',\n    template: '%s | My Awesome Site',\n  },\n  description: 'Description of my awesome website',\n  openGraph: {\n    title: 'My Awesome Site',\n    description: 'Description of my awesome website',\n    url: 'https:\u002F\u002Fmyawesomesite.com',\n    siteName: 'My Awesome Site',\n    images: [\n      {\n        url: 'https:\u002F\u002Fmyawesomesite.com\u002Fog-image.jpg',\n        width: 1200,\n        height: 630,\n      },\n    ],\n    locale: 'en_US',\n    type: 'website',\n  },\n  twitter: {\n    card: 'summary_large_image',\n    title: 'My Awesome Site',\n    creator: '@username',\n  },\n  robots: {\n    index: true,\n    follow: true,\n  },\n};\n\n\u002F\u002F Dynamic metadata\nexport async function generateMetadata({ params }): Promise\u003CMetadata> {\n  const product = await getProduct(params.id);\n  \n  return {\n    title: product.name,\n    description: product.description,\n    openGraph: {\n      images: [product.image],\n    },\n  };\n}\n```\n\n### Structured Data\n\n```javascript\n\u002F\u002F components\u002FProductSchema.tsx\nexport function ProductSchema({ product }) {\n  const schema = {\n    '@context': 'https:\u002F\u002Fschema.org',\n    '@type': 'Product',\n    name: product.name,\n    description: product.description,\n    image: product.images,\n    offers: {\n      '@type': 'Offer',\n      price: product.price,\n      priceCurrency: product.currency,\n      availability: product.inStock \n        ? 'https:\u002F\u002Fschema.org\u002FInStock' \n        : 'https:\u002F\u002Fschema.org\u002FOutOfStock',\n    },\n    aggregateRating: product.rating ? {\n      '@type': 'AggregateRating',\n      ratingValue: product.rating.value,\n      reviewCount: product.rating.count,\n    } : undefined,\n  };\n  \n  return (\n    \u003Cscript\n      type=\"application\u002Fld+json\"\n      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n    \u002F>\n  );\n}\n\n\u002F\u002F JSON-LD for organization\nexport function OrganizationSchema() {\n  const schema = {\n    '@context': 'https:\u002F\u002Fschema.org',\n    '@type': 'Organization',\n    name: 'Company Name',\n    url: 'https:\u002F\u002Fcompany.com',\n    logo: 'https:\u002F\u002Fcompany.com\u002Flogo.png',\n    contactPoint: {\n      '@type': 'ContactPoint',\n      telephone: '+1-555-555-5555',\n      contactType: 'customer service',\n    },\n  };\n  \n  return (\n    \u003Cscript\n      type=\"application\u002Fld+json\"\n      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n    \u002F>\n  );\n}\n```\n\n### Sitemap Generation\n\n```javascript\n\u002F\u002F app\u002Fsitemap.ts\nimport { MetadataRoute } from 'next';\n\nexport default async function sitemap(): Promise\u003CMetadataRoute.Sitemap> {\n  const baseUrl = 'https:\u002F\u002Fmyawesomesite.com';\n  \n  \u002F\u002F Fetch dynamic content\n  const posts = await getAllPosts();\n  const products = await getAllProducts();\n  \n  const staticPages = [\n    '',\n    '\u002Fabout',\n    '\u002Fcontact',\n    '\u002Fpricing',\n  ].map((route) => ({\n    url: `${baseUrl}${route}`,\n    lastModified: new Date(),\n    changeFrequency: 'monthly' as const,\n    priority: route === '' ? 1 : 0.8,\n  }));\n  \n  const blogPosts = posts.map((post) => ({\n    url: `${baseUrl}\u002Fblog\u002F${post.slug}`,\n    lastModified: new Date(post.updatedAt),\n    changeFrequency: 'weekly' as const,\n    priority: 0.7,\n  }));\n  \n  const productPages = products.map((product) => ({\n    url: `${baseUrl}\u002Fproducts\u002F${product.id}`,\n    lastModified: new Date(product.updatedAt),\n    changeFrequency: 'daily' as const,\n    priority: 0.9,\n  }));\n  \n  return [...staticPages, ...blogPosts, ...productPages];\n}\n```\n\n-----\n\n## Performance Optimization\n\n### Bundle Analysis\n\n```javascript\n\u002F\u002F next.config.js\nconst withBundleAnalyzer = require('@next\u002Fbundle-analyzer')({\n  enabled: process.env.ANALYZE === 'true',\n});\n\nmodule.exports = withBundleAnalyzer({\n  experimental: {\n    optimizePackageImports: ['lodash', 'moment', 'antd'],\n  },\n  webpack: (config, { isServer }) => {\n    \u002F\u002F Optimize third-party imports\n    if (!isServer) {\n      config.resolve.fallback = {\n        ...config.resolve.fallback,\n        fs: false,\n        net: false,\n        tls: false,\n      };\n    }\n    return config;\n  },\n});\n```\n\n### Font Optimization\n\n```javascript\n\u002F\u002F app\u002Flayout.tsx\nimport { Inter, JetBrains_Mono } from 'next\u002Ffont\u002Fgoogle';\n\nconst inter = Inter({\n  subsets: ['latin'],\n  display: 'swap',\n  variable: '--font-inter',\n});\n\nconst jetbrainsMono = JetBrains_Mono({\n  subsets: ['latin'],\n  display: 'swap',\n  variable: '--font-mono',\n});\n\nexport default function RootLayout({ children }) {\n  return (\n    \u003Chtml lang=\"en\" className={`${inter.variable} ${jetbrainsMono.variable}`}>\n      \u003Cbody>{children}\u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  );\n}\n```\n\n### Image Optimization\n\n```javascript\n\u002F\u002F components\u002FOptimizedImage.tsx\nimport Image from 'next\u002Fimage';\n\nexport function ProductImage({ src, alt, priority = false }) {\n  return (\n    \u003CImage\n      src={src}\n      alt={alt}\n      width={600}\n      height={400}\n      sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\"\n      priority={priority}\n      placeholder=\"blur\"\n      blurDataURL={generateBlurPlaceholder(src)}\n    \u002F>\n  );\n}\n\n\u002F\u002F Use responsive sizes properly\nexport function Gallery({ images }) {\n  return (\n    \u003Cdiv className=\"gallery\">\n      {images.map((img) => (\n        \u003CImage\n          key={img.id}\n          src={img.src}\n          alt={img.alt}\n          fill\n          sizes=\"(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw\"\n          style={{ objectFit: 'cover' }}\n        \u002F>\n      ))}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n-----\n\n## Best Practices\n\n1. **Default to Server Components** — Only use client components when necessary for interactivity.\n\n2. **Minimize Client Bundle** — Import server-only modules at the top level.\n\n3. **Use Streaming Strategically** — Wrap slow data fetches in Suspense boundaries.\n\n4. **Implement Proper Caching** — Use appropriate cache strategies for each data type.\n\n5. **Optimize Images and Fonts** — Use Next.js built-in optimizations.\n\n6. **Monitor Core Web Vitals** — Track LCP, FID, and CLS in production.\n\n7. **Use Edge Functions Judiciously** — They're fast but have limits on computation.\n\n8. **Plan for Incremental Migration** — You don't need to convert everything at once.\n",{"name":5,"license":15,"metadata":60,"description":65,"compatibility":46},{"tags":61,"audience":63,"category":64},[53,48,62,47,35],"hydration","web-developers","web-development","Expert guidance on server-side rendering for improved performance and SEO. Use for:  React SSR with Next.js, Vue SSR with Nuxt, hydration strategies, server state management,  streaming SSR, edge rendering, caching strategies, SEO optimization, and building  performance-critical web applications.\n","main","2ea764e153842704d24a2e9aa4170441a7f03081",".opencode\u002Fskills\u002Fserverside-rendering","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito","https:\u002F\u002Fgithub.com\u002FNeuralBlitz","nuralnexus.org","Independent Multidisciplinary Researcher, Creative Producer, and AI Systems Architect\r\nAn independent creator and research-driven systems designer.","2026-11-12 03:13:05",{"source":8,"skillName":5,"commands":75,"prompt":85,"zipAvailable":86},[76,79,82],{"tool":77,"command":78},"npx","npx skills add NeuralBlitz\u002FMito --skill serverside-rendering",{"tool":80,"command":81},"bunx","bunx skills add NeuralBlitz\u002FMito --skill serverside-rendering",{"tool":83,"command":84},"pnpm","pnpm dlx skills add NeuralBlitz\u002FMito --skill serverside-rendering","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fserverside-rendering\u002FSKILL.md",true,[],[89,105,118,131,139,160],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":55},"01M6HAZSAQK1S27CEZYAYJTQDX","wireless-communications","Wireless systems, mobile networks, and 5G\u002F6G","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fwireless-communications\u002FSKILL.md",[],[96,97,98,99,100,101,102,103,46,104],"communications","wireless communications","wireless","systems","engineering","networks","5G","students","mobile",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":55},"01M6HAZFX6E8NK3WZWDX5YCKYY","websockets","WebSocket implementation and best practices","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fwebassembly\u002Fwebsockets\u002FSKILL.md",[],[107,112,113,114,46,115,116,117],"websocket implementation","time","implementation","real-time","websocket","best practices",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":55},"01M6HAZ6DAXBQ7QHXXM1EM7715","vulnerability-auditing","Vulnerability assessment and auditing","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fvulnerability-auditing\u002FSKILL.md",[],[125,126,127,128,46,129,130],"vulnerability","vulnerability auditing","security","vulnerability assessment","cybersecurity","assessment",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":55},"01M6HAZ3FKF3CS9Z3J96RVE2ZE","vulnerability-assessment","Finding and assessing security vulnerabilities","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fvue\u002Fvulnerability-assessment\u002FSKILL.md",[],[128,125,130,127,138,46],"vulnerabilities",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":151,"publishedAt":55},"01M6HAYSHM6HKRKEHFP0SGZQX7","vlsi-design","Very-Large-Scale Integration circuit design and semiconductor engineering","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fvlsi-design\u002FSKILL.md",[145,148],{"categoryNo":146,"categoryName":147,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":149,"categoryName":150,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000032","设计师",[152,153,154,155,156,100,157,46,158,103,159],"vlsi design","VLSI","design","hardware","integration","computer","scale","circuit",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":166,"publishedAt":55},"01M6HAYPQ30FFE2JXD7WQJ8R6C","unsupervised","Unsupervised learning concepts","https:\u002F\u002Fgithub.com\u002FNeuralBlitz\u002FMito\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fvisualization\u002Funsupervised\u002FSKILL.md",[],[162,167,46,168,169,170,171,172],"learning","intelligence","unsupervised learning","machine","concepts","machine-learning"]