Panduan Remix SEO
Bagaimana Remix's meta(), loader(), headers(), dan tautan() route exports control SEO — plus apa changed sebagai Remix v2 menjadi React Router, now pada v8.
TL;DR — Remix adalah sebuah React kerangka kerja itu renders Anda halaman pada server oleh default — so konten adalah sudah di HTML sebelum Google ever memuat ini. itu goes sebuah panjang cara toward solving biggest JavaScript SEO masalah, though ini tidak jaminan pengindeksan atau rankings oleh itself. Anda masih memiliki untuk set Anda judul, deskripsi, dan tag canonical yourself, menggunakan Remix’s per-route
meta()function. SSR adalah foundation, tidak seluruh house. Note: Remix v2 digabungkan ke React Router (now v8) — Remix 3 (beta) adalah sebuah terpisah, newer product; ini halaman covers Remix v2 / React Router route API sebagian besar situs jalankan hari ini.
Apa Remix adalah
Remix routes dapat render pada server dan menyediakan document metadata melalui route APIs. Bukti untuk klaim ini Primary standard or official documentation supporting the adjacent article claim. Cakupan: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Tingkat keyakinan: tinggi · Diverifikasi: Remix: Route meta server-dirender HTML improves awal konten pengiriman tetapi melakukan tidak jaminan Penelusuran pengindeksan. Bukti untuk klaim ini Primary standard or official documentation supporting the adjacent article claim. Cakupan: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Tingkat keyakinan: tinggi · Diverifikasi: Google: JavaScript SEO basics
Remix adalah sebuah meta-kerangka kerja dibangun pada React. Plain React membangun Anda seluruh halaman di browser dengan JavaScript — Google mendapatkan sebuah nearly empty HTML file dan memiliki untuk jalankan Anda code untuk see apa pun. Remix flips itu: ini berjalan Anda React components pada server dan mengirim back finished HTML dengan text, tautan, dan meta tags sudah di ini. server rendering adalah kerangka kerja default — sebuah project dapat juga menjadi configured untuk statically prerender routes atau jalankan di SPA mode, so konfirmasi yang mode sebuah diberikan situs sebenarnya menggunakan alih-alih assuming dari kerangka kerja name alone.
untuk SEO, itu’s sebuah huge head mulai pada default SSR path. ada Tidak menunggu untuk JavaScript, Tidak “render queue,” (terjemahan) “render queue,” dan crawler itu jangan jalankan JavaScript di semua (banyak AI bot, social preview bot) masih mendapatkan Anda penuh konten.
Satu naming note itu trips orang up, dan ini adalah lebih layered daripada ini digunakan untuk menjadi:
di late 2024 Remix team digabungkan Remix v2’s application APIs ke React
Router v7 — sama route exports (meta, loader, headers, links,
ErrorBoundary), renamed package. React Router memiliki since moved untuk v8 (June
2026), dengan v7 masih receiving security memperbarui. Secara terpisah, Remix name now
juga refers untuk Remix 3, sebuah newer beta penuh-stack kerangka kerja team mendeskripsikan
sebagai “a berbeda direction” (terjemahan) “sebuah berbeda direction” dari React Router — sebuah distinct product, tidak hanya sebuah
renamed satu. Semuanya pada ini halaman documents Remix v2 / React Router v7-v8
route API itu sebagian besar production Remix situs jalankan hari ini; ini melakukan tidak cover Remix 3.
Bagaimana Anda tambahkan SEO tags di Remix
Remix memberikan setiap route (setiap halaman) special functions Anda export dari file:
meta()— sets Anda<title>, deskripsi meta, Open Graph tags, dan bahkan data terstruktur. ini adalah main SEO alat.loader()— fetches data pada server (like sebuah blog post dari Anda database) sebelum HTML adalah dikirim. Andameta()dapat gunakan itu data, so judul dapat menjadi dynamic.links()— menambahkan<link>tags like favicons dan stylesheets.headers()— sets respons header HTTP (caching, robots aturan).
Di sini’s simplest versi dari sebuah judul dan deskripsi:
export const meta = () => {
return [
{ title: "About Us | My Site" },
{ name: "description", content: "Learn about our team and mission." },
];
};itu renders straight ke server HTML — persis di mana Google ingin ini.
satu mistake untuk hindari
paling umum Remix SEO bug: child halaman diam-diam lose meta tags set oleh
parent layouts. Remix hanya mempertahankan deepest route’s meta() dan throws away
rest unless Anda tell ini tidak untuk. jika Anda homepage layout sets sebuah situs-wide
deskripsi dan Anda tentang halaman exports -nya own meta() tanpa merging,
deskripsi disappears pada itu halaman. perbaiki adalah di Advanced tab.
sederhana takeaway
- Remix adalah sebuah safe SEO pilihan karena ini adalah server-dirender oleh default.
- Anda masih memiliki untuk tulis Anda judul, deskripsi, dan canonicals dengan
meta(). - Watch out untuk child halaman dropping parent meta tags.
ingin nyata versi — loader dan nyata 404s, headers() untuk X-Robots-Tag,
tag canonical dua cara, dan React Router v7 migration? Switch untuk
Advanced tab. untuk kerangka kerja-agnostic background, see
JavaScript SEO dan
JavaScript kerangka kerja hub.
TL;DR — Remix adalah SSR-oleh-default, so konten ships di awal HTML dengan Tidak render-queue dependency — architecture menghapus sebagian besar JS-SEO risk ketika SSR adalah apa sebenarnya deployed, though ini tidak oleh itself jaminan pengindeksan, peringkat, atau Core Web Vitals outcomes. berfungsi adalah di per-route exports:
meta()(judul, deskripsi, OG, JSON-LD, dan dynamic canonicals melaluitagName: "link"),loader()(server data + nyata HTTP 404s/redirects),headers()(Cache-Control,X-Robots-Tag), danlinks()(static canonicals, preloads). signature gotcha: nested routes drop parent meta unless Anda gabungkan ini melaluimatchesargument. Naming, dated: Remix v2’s APIs digabungkan ke React Router v7 di 2024; React Router adalah now pada v8 (v7 masih security-didukung); Remix 3 (beta) adalah sebuah terpisah, newer penuh-stack kerangka kerja, tidak sekadar React Router renamed. ini halaman covers Remix v2 / React Router v7-v8 route API.
SSR oleh default — mengapa Remix dimulai ahead
Remix’s server rendering adalah sebuah kerangka kerja kemampuan milik siapa deployment perilaku bergantung pada adapter dan route code. Bukti untuk klaim ini Primary standard or official documentation supporting the adjacent article claim. Cakupan: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Tingkat keyakinan: tinggi · Diverifikasi: Remix: Route meta Validate delivered HTML dan resources alih-alih assuming sebuah kerangka kerja default ensures SEO outcomes. Bukti untuk klaim ini Primary standard or official documentation supporting the adjacent article claim. Cakupan: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Tingkat keyakinan: tinggi · Diverifikasi: Google: JavaScript SEO basics
Cakupan note: walkthrough di bawah documents meta() / loader() /
headers() / links() / ErrorBoundary route module API sebagai ini ada di Remix
v2 dan React Router v7-v8 kerangka kerja mode — apa besar majority dari production
Remix/React Router situs jalankan. Remix 3 (beta) adalah sebuah terpisah, ground-up rewrite
dengan berbeda APIs dan tidak covered di sini; periksa yang satu Anda’re sebenarnya pada
sebelum copying apa pun di bawah.
Bare React (CRA, Vite + React) ships sebuah empty <div id="root"></div> dan membangun
halaman di browser. Google dapat render itu, tetapi Anda’ve signed up untuk
render queue, statelessness, dan DOM-parity masalah covered di
JavaScript SEO. Remix tidak memiliki itu default:
ini executes Anda nested route tree (Root → Layout → Route) pada server dan, oleh
default, mengirim konten-menyelesaikan HTML pada setiap document permintaan. kerangka kerja mode
dapat juga menjadi configured untuk statically prerender routes di bangun time atau jalankan sebagai sebuah
client-dirender SPA — so untuk apa pun diberikan deployment, konfirmasi sebenarnya rendering
mode (melalui curl/View Sumber, di bawah) alih-alih assuming SSR dari kerangka kerja
name.
«Google’s own guidance lines up with this. From the JavaScript SEO basics doc:
“Server-side or pre-rendering is still a great idea because it makes your website
faster for users and crawlers, and not all bots can run JavaScript.” That last
clause is the whole argument for Remix — Bingbot renders JS slowly and incompletely,
and many AI crawlers and social preview bots (Twitterbot, facebookexternalhit)
don’t render at all. Remix’s SSR output serves all of them correctly without special
handling.
» (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian dua puluh tujuh, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)
setelah awal muat, Remix menggunakan client-side routing untuk subsequent navigations
(like setiap React kerangka kerja). itu’s fine: Google discovers tautan dari SSR’d
HTML dan melakukan crawl setiap URL sebagai -nya own server permintaan — setiap returning penuh HTML. ini
tidak rely pada watching client-side route transitions. dan karena Remix’s <Link>
renders sebuah nyata <a href>, tautan adalah dapat di-crawl oleh construction — Google
“dapat hanya discover Anda links jika they adalah <a> HTML elements dengan an href
attribute.” (terjemahan) “dapat hanya menemukan Anda tautan jika mereka adalah tidak terdefinisi HTML elements dengan sebuah tidak terdefinisi
attribute.”
meta() export: judul, deskripsi, OG, JSON-LD
setiap route dapat export sebuah meta function returning sebuah array dari descriptor objects.
Karena ini dapat baca loader data, metadata adalah dynamic dan set di awal HTML
<head> — Tidak JS-injection delay:
// app/routes/blog.$slug.tsx
import type { MetaFunction } from "@remix-run/node";
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [{ title: "Post Not Found" }];
return [
{ title: `${data.post.title} | My Blog` },
{ name: "description", content: data.post.excerpt },
{ property: "og:title", content: data.post.title },
{ property: "og:image", content: data.post.ogImage },
{ property: "og:type", content: "article" },
{
"script:ld+json": {
"@context": "https://schema.org",
"@type": "Article",
headline: data.post.title,
datePublished: data.post.publishedAt,
author: { "@type": "Person", name: data.post.author },
},
},
];
};{ "script:ld+json": {...} } descriptor renders sebuah proper
<script type="application/ld+json"> tag di SSR’d <head> — terlihat untuk Google’s
parser tanpa executing apa pun JavaScript. Martin Splitt’s preference applies:
“We dukung JSON-LD di dynamically dirender konten, tetapi ini generally better untuk
memiliki it di itu awal HTML.” (terjemahan) “kami mendukung JSON-LD di dynamically dirender konten, tetapi ini adalah umumnya better untuk
memiliki ini di awal HTML.” di Remix, awal HTML adalah default place ini
lands.
Nested routes dan meta inheritance — umum trap
ini adalah Remix SEO mistake. Remix takes terakhir matching route dengan sebuah meta
export dan menggunakan itu — parent meta adalah dropped. A child itu exports its own
meta() tanpa merging silently loses setiap tag itu root set (site-wide
description, root OG tags, dan seterusnya.):
// ❌ Root's description is now gone on this route
export const meta: MetaFunction = () => {
return [{ title: "About Us" }];
};perbaiki adalah matches argument — flatten dan spread parent meta:
// ✅ Keep parent meta, append your own
export const meta: MetaFunction = ({ matches }) => {
const parentMeta = matches.flatMap((match) => match.meta ?? []);
return [...parentMeta, { title: "About Us" }];
};
// ✅ Keep parent meta but override only the title
export const meta: MetaFunction = ({ matches }) => {
const parentMeta = matches
.flatMap((match) => match.meta ?? [])
.filter((meta) => !("title" in meta));
return [...parentMeta, { title: "About Us" }];
};jika Anda set global tags, put truly universal ones (charset, viewport) secara langsung di
root.tsx’s JSX di mana merging tidak pernah strips them, dan reserve meta() untuk
halaman-tingkat sinyal Anda sebenarnya ingin untuk override per route.
loader() function: nyata 404s, nyata redirects, dynamic meta
Loaders jalankan server-side hanya — DB kueri, API panggilan, dan secrets tidak pernah reach Googlebot. SEO payoff adalah correct HTTP kode status:
// app/routes/products.$id.tsx
import { json, redirect } from "@remix-run/node";
import type { LoaderFunctionArgs } from "@remix-run/node";
export async function loader({ params }: LoaderFunctionArgs) {
const product = await db.products.findById(params.id);
if (!product) {
throw new Response("Product not found", { status: 404 });
// ✅ real HTTP 404 — not a soft 404
}
if (product.movedTo) {
throw redirect(`/products/${product.movedTo}/`, 301); // ✅ real 301
}
return json(product);
}«This is the antidote to the soft-404 problem SPAs create — a 200 OK page that
just says “not found.” As John Mueller put it: “If a page returns a 200 but there’s
no content — that’s a soft 404. That’s problematic because we don’t know to treat it
as a 404. From a crawling standpoint, we’ll just keep trying to crawl it.” Remix’s
throw new Response(..., { status: 404 }) propagates a genuine 404, which lines up
with Google’s instruction to “use a meaningful status code, like a 404 for a page
that could not be found.”
» (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian empat puluh dua, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)
Whatever sebuah loader mengembalikan adalah exposed untuk client bahkan jika component tidak render ini — treat loaders like publik API endpoints dan jangan kembalikan secrets.
ini status propagation adalah apa happens pada sebuah direct document permintaan ( case sebuah crawler membuat). Client-side navigations setelah hydration adalah sebuah terpisah code path itu dapat behave differently, dan beberapa hosting adapters rewrite atau intercept thrown respons — verify keduanya direct-permintaan dan post-hydration perilaku pada Anda sebenarnya deployment alih-alih assuming ini dari loader code alone.
headers() function: Cache-Control dan X-Robots-Tag
Per-route header HTTP — lever untuk CDN caching (lebih cepat TTFB → better Core Web Vitals) dan untuk robots directives itu berfungsi bahkan pada crawler itu jangan baca HTML body:
import type { HeadersFunction } from "@remix-run/node";
// CDN-friendly caching
export const headers: HeadersFunction = () => ({
"Cache-Control": "max-age=300, s-maxage=3600, stale-while-revalidate=86400",
});
// HTTP-level noindex — effective for Bingbot and non-rendering crawlers
export const headers: HeadersFunction = () => ({
"X-Robots-Tag": "noindex, nofollow",
});X-Robots-Tag: noindex di header tingkat reaches crawler itu tidak pernah parse
body. oleh default hanya deepest route’s headers() berjalan di sebuah nested tree, so
simplest pattern adalah untuk define headers pada leaf routes hanya dan hindari gabungkan
complexity.
sebuah meta-noindex caveat worth knowing regardless dari kerangka kerja, dari Martin Splitt:
“Itu noindex tag dapat penyebab Google untuk skip rendering entirely. So jika Anda trying
untuk noindex melalui JavaScript, Anda mungkin menjadi creating a situation di mana Google never even
berjalan itu JavaScript untuk see itu noindex.” (terjemahan) “ tidak terdefinisi tag dapat penyebab Google untuk skip rendering entirely. So jika Anda’re trying
untuk tidak terdefinisi melalui JavaScript, Anda dapat menjadi membuat sebuah situation di mana Google tidak pernah bahkan
berjalan JavaScript untuk see noindex.” Remix sidesteps ini karena directive
lands di SSR’d <head> (atau sebuah header HTTP), tidak di client-hanya JavaScript.
links() export dan tag canonical — dua cara
links() injects <link> elements (favicons, stylesheet preloads, static
canonicals). tetapi ini memiliki Tidak access untuk loader data — ini adalah static per route module:
export const links: LinksFunction = () => [
{ rel: "canonical", href: "https://example.com/canonical-url/" },
];untuk dynamic canonicals — paginated, filtered, atau parameterized URLs — gunakan meta()
dengan tagName: "link", yang melakukan see data, params, dan location:
export const meta: MetaFunction<typeof loader> = ({ data }) => [
{
tagName: "link",
rel: "canonical",
href: `https://example.com/products/${data.product.slug}/`,
},
];aturan: static canonical → links(); dynamic canonical → meta() dengan
tagName: "link". ini matches Martin Splitt’s advice untuk set canonicals di HTML
alih-alih JavaScript — “set Anda canonical di itu HTML, tidak dengan JavaScript… ini
sekadar lebih fragile.” (terjemahan) “set Anda canonical di HTML, tidak dengan JavaScript… ini adalah
hanya lebih fragile.” Keduanya Remix approaches render ke server HTML. (See
tag canonical deep dive.)
Error boundaries dan 404/5xx halaman
Ketika sebuah loader, tindakan, atau component throws, route’s ErrorBoundary renders — di
place, di dalam surviving layout (nav, footer stay). Paired dengan sebuah thrown 404
respons, Anda mendapatkan sebuah nyata 404 status dan sebuah usable halaman:
import { isRouteErrorResponse, useRouteError } from "@remix-run/react";
export function ErrorBoundary() {
const error = useRouteError();
if (isRouteErrorResponse(error) && error.status === 404) {
return <div><h1>404 — Page Not Found</h1></div>;
}
return <div>Something went wrong.</div>;
}sebuah root-tingkat ErrorBoundary di app/root.tsx catches apa pun route boundaries
jangan. myth itu “throwing a 404 breaks itu layout” (terjemahan) “throwing sebuah 404 breaks layout” adalah salah — boundary
renders di dalam route hierarchy.
Sitemaps dan robots.txt sebagai routes
Remix memiliki Tidak dibangun-di sitemap generator; Anda bangun them sebagai resource routes.
bracket notation escapes dot so URL adalah secara harfiah /sitemap.xml:
// app/routes/sitemap[.xml].tsx
export async function loader() {
const posts = await db.posts.findMany({ where: { published: true } });
const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${posts.map((p) => ` <url><loc>https://example.com/blog/${p.slug}/</loc><lastmod>${p.updatedAt.toISOString()}</lastmod></url>`).join("\n")}
</urlset>`;
return new Response(body, {
headers: { "Content-Type": "application/xml", "Cache-Control": "public, max-age=3600" },
});
}robots.txt mengikuti yang sama app/routes/robots[.txt].tsx pattern, returning
text/plain.
Remix, React Router, dan 2026 product split — sebuah dated timeline
ini memiliki gotten lebih layered since original 2024 gabungkan, so treat ini sebagai history plus saat ini state alih-alih sebuah single fact:
- Dec 2024 — Remix v2 merges ke React Router v7.
@remix-run/reactdan@remix-run/nodeconsolidate kereact-router;@remix-run/*packages masih berfungsi sebagai sebuah bridge. apa SEO-relevant dari ini move: routes.ts— sebuah routing config file; routes dapat menjadi didefinisikan programmatically untuk lebih flexible struktur URL.- Static pre-rendering — individual routes dapat opt ke bangun-time HTML generation (SSG-style), atau SPA mode — configuration choices, tidak automatic.
- End-untuk-end jenis safety —
loaderkembalikan jenis flow kemeta(), reducing bugs di dynamic meta generation. - Vite — default bundler since Remix v2; route-tingkat code splitting mempertahankan client bundles lean (baik untuk TBT/LCP).
- Apa tidak perubahan:
meta()/loader()/headers()/links()/ErrorBoundarypattern dan<Meta />/<Links />/<Scripts />components diroot.tsx. Existing Remix v2 SEO code carries di atas dengan minimal perubahan. - June 2026 — React Router v8 ships. React Router v7 tetap security-didukung;
Remix v2 dan React Router v6 adalah now end-dari-life. route module SEO API ini
halaman documents (
meta,loader,headers,links,ErrorBoundary) adalah yang sama shape di seluruh v7 dan v8 — periksa Anda installed versi’s changelog untuk apa pun descriptor-tingkat perubahan sebelum copying code verbatim. - juga sebagai dari 2026 — Remix adalah Tidak lebih lama hanya “the old name for React Router.” (terjemahan) “ old name untuk React Router.”
Remix team mendeskripsikan React Router sebagai mereka React meta-kerangka kerja, dan Remix
(now di sebuah “Remix 3” (terjemahan) “Remix 3” beta) sebagai sebuah terpisah, newer penuh-stack kerangka kerja — “satu team,
dua projects.” (terjemahan) “satu team,
dua projects.” jika Anda’re auditing atau membangun pada
@remix-run/*/react-routerroute exports, ini artikel’s API guidance applies secara langsung. jika Anda’re pada Remix 3, verify -nya documentation independently — meta/loader/headers/tautan pattern described di sini adalah tidak confirmed untuk carry di atas unchanged.
Bottom line untuk sebagian besar situs di production hari ini: “Remix SEO” (terjemahan) “Remix SEO” dan “React Router SEO” (terjemahan) “React Router SEO” adalah masih yang sama route API dan yang sama practical topic. hanya jangan assume itu juga covers Remix 3.
Anda masih jangan perlu dynamic rendering
Karena Remix menyajikan HTML pada server, Anda tidak pernah perlu Rendertron atau Prerender.io. Google deprecated dynamic rendering anyway: “Dynamic rendering was a workaround and not a long-term solution… it creates additional complexities and resource requirements.” (terjemahan) “Dynamic rendering adalah sebuah workaround dan tidak sebuah panjang-istilah solusi… ini membuat additional complexities dan resource requirements.” SSR adalah recommended path, dan Remix memberikan ini untuk Anda oleh default.
Auditing sebuah Remix situs
- periksa awal HTML dengan
curlatau View Sumber — tidak DevTools Elements (yang menampilkan post-hydration DOM). - Verify nyata HTTP kode status pada missing halaman (404, tidak 200) dan redirects (301/302).
- Test dengan GSC pemeriksaan URL — Remix’s disajikan HTML seharusnya match dirender view.
- cari nested-meta gabungkan bugs — konfirmasi child halaman masih carry situs-wide deskripsi dan OG tags.
- Validate JSON-LD dengan Rich hasil Test, dan jalankan sebuah crawl (Ahrefs situs Audit, Screaming Frog) untuk catch blocked assets dan depth issues.
None dari di atas adalah sebuah jaminan dari pengindeksan, rankings, atau Core Web Vitals — SSR, correct kode status, dan bersih metadata hapus architecture-tingkat risk; rest masih bergantung pada konten quality, deployment adapter, dan bagaimana halaman performs terhadap semuanya else di SERP.
untuk base library underneath Remix, see React SEO; untuk kerangka kerja-agnostic rendering aturan, see JavaScript SEO dan JavaScript kerangka kerja hub.
AI summary
sebuah condensed take pada Advanced versi:
- Remix adalah SSR-oleh-default — ini renders nested route tree pada server dan,
oleh default, ships konten-menyelesaikan HTML pada setiap document permintaan (kerangka kerja mode
dapat juga menjadi atur ke static prerender atau SPA, so verify sebenarnya deployed mode).
Tidak render queue, Tidak empty root
<div>, dan non-rendering crawler (Bingbot, AI bot, social bot) mendapatkan penuh konten — though none dari ini jaminan pengindeksan atau rankings oleh itself. meta()adalah utama SEO alat — judul, deskripsi, OG, JSON-LD ("script:ld+json"), dan dynamic canonicals melaluitagName: "link". ini dapat bacaloaderdata, so metadata adalah konten-spesifik dan di awal HTML.- ** signature gotcha:** nested routes gunakan deepest route’s
metadan drop parent meta unless Anda gabungkan ini denganmatchesargument. loader()berjalan server-side;throw new Response("", { status: 404 })memberikan sebuah nyata 404 (Tidak soft 404) danthrow redirect()memberikan sebuah nyata 301/302.headers()setsCache-Control(TTFB/CWV) danX-Robots-Tagdi HTTP tingkat — berfungsi bahkan untuk crawler itu jangan baca body.links()vsmeta()untuk canonicals:links()adalah static (Tidak loader data);meta()dengantagName: "link"adalah dynamic. Static →links(), dynamic →meta().ErrorBoundaryrenders di dalam surviving layout dan pairs dengan thrown 404s untuk correct status + usable halaman.- Remix v2’s APIs digabungkan ke React Router v7 (Dec 2024) — sama SEO APIs,
renamed packages (
react-router), baruroutes.ts, opsional static pre-rendering, Vite bundling. React Router adalah now pada v8 (June 2026; v7 masih security-didukung). Secara terpisah, Remix 3 (beta) adalah sebuah newer, distinct penuh-stack kerangka kerja — tidak hanya React Router di bawah old name. ini artikel covers Remix v2 / React Router v7-v8 route API. Tidak dynamic rendering alat needed untuk itu API either cara.
Dokumentasi resmi
Utama-sumber documentation dari Remix / React Router dan mesin pencari.
Remix / React Router
- Remix —
metafunction — per-route meta tags, descriptors, danmatchesmerging. - Remix —
loaderfunction — server-side data fetching dan thrown respons. - Remix —
headersfunction — per-route respons header HTTP. - Remix —
linksfunction —<link>elements (canonical, preload, favicon). - Remix —
ErrorBoundary— route dan root error menangani. - React Router v7 announcement — Remix v2 → React Router gabungkan (Dec 2024).
- React Router v8 — saat ini rilis (June 2026) dan “one team, two projects” (terjemahan) “satu team, dua projects” note pada bagaimana Remix 3 now differs dari React Router.
- React Router docs — di mana Remix v2-lineage route API now lives, saat ini pada v8.
- memahami JavaScript SEO basics — three-phase crawl/render/indeks proses, kode status,
<a href>tautan, dan SSR guidance. - Dynamic rendering (deprecated) — mengapa dynamic rendering adalah sebuah workaround, tidak sebuah solusi.
- di-Depth Guide untuk Bagaimana Google Search berfungsi — di mana rendering sits di crawl → indeks → sajikan.
Quotes dari sumber
pada—record statements dari Google itu bear secara langsung pada Remix’s SSR-pertama model. setiap penelusuran-mesin tautan adalah sebuah deep tautan itu jumps untuk quoted passage.
Google — mengapa SSR helps
«- “Server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript.”
Jump to quote
» (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian sembilan puluh, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)
«- “Google can only discover your links if they are <a> HTML elements with an href attribute.”
Jump to quote
» (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian sembilan puluh, bagian kecil dua: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)
Google — kode status ( loader + ErrorBoundary pattern)
- “Untuk tell Googlebot jika a halaman tidak dapat menjadi crawled atau indexed, gunakan a bermakna status code, like a 404 untuk a halaman itu could tidak menjadi ditemukan atau a 401 code untuk halaman behind a login.” (terjemahan) “untuk tell Googlebot jika sebuah halaman dapat’t menjadi di-crawl atau terindeks, gunakan bermakna kode status, like sebuah 404 untuk sebuah halaman itu dapat tidak menjadi ditemukan atau sebuah 401 code untuk halaman behind sebuah login.” Jump untuk quote
Google — dynamic rendering adalah deprecated
- “Dynamic rendering adalah a workaround dan tidak a long-term solution untuk problems dengan JavaScript-generated konten di penelusuran engines.” (terjemahan) “Dynamic rendering adalah sebuah workaround dan tidak sebuah panjang-istilah solusi untuk masalah dengan JavaScript-generated konten di mesin pencari.” Jump untuk quote
Remix SEO checklist
sebuah quick lulus untuk apa pun Remix / React Router v7 project:
- penting halaman adalah server-dirender ( default) — konfirmasi konten adalah di
View Sumber /
curl, tidak hanya post-hydration DOM. - setiap dapat diindeks route sets sebuah
<title>dan deskripsi meta melaluimeta()export. - Child routes itu export
meta()gabungkan parent meta melaluimatchesargument (Tidak dropped situs-wide tags). - Missing resources
throw new Response(..., { status: 404 })diloader— verify sebuah nyata 404, tidak sebuah soft 404 (200 + “tidak ditemukan” (terjemahan) “tidak ditemukan”). - Moved URLs
throw redirect(target, 301)dari loader — nyata 301/302. - tag canonical adalah set di HTML:
links()untuk static,meta()dengantagName: "link"untuk dynamic (paginated/filtered/param URLs). -
noindexadalah set di SSR’d<head>atau melaluiheaders()X-Robots-Tag— tidak pernah client-side hanya. -
headers()sets sensibleCache-Controluntuk CDN caching / TTFB pada leaf routes. - JSON-LD adalah ditambahkan melalui
{ "script:ld+json": {...} }dimeta()dan validated di Rich hasil Test. -
sitemap.xmldanrobots.txtexist sebagai resource routes (sitemap[.xml].tsx,robots[.txt].tsx) dan adalah submitted di Search Console. - tautan internal gunakan Remix
<Link>(renders nyata<a href>). - Tidak
@remix-run/*→react-routerrename surprises jika Anda’re migrating untuk v7.
mental models
1. SSR adalah floor, tidak ceiling.
Remix renders pada server oleh default, yang menghapus penemuan/rendering risk
class untuk free. ini melakukan tidak auto-tangani judul, deskripsi, canonicals,
data terstruktur, cache headers, atau 404 kode status — setiap adalah sebuah jelas meta(),
headers(), links(), atau loader decision. SSR adalah sebuah prerequisite, tidak sebuah menyelesaikan
SEO solusi.
2. right export untuk right sinyal.
- HTML
<head>tags (judul, deskripsi, OG, JSON-LD, dynamic canonical) →meta() - Static
<link>elements (favicon, preload, static canonical) →links() - HTTP kode status (404, 301, 302) dan server data →
loader() - respons header HTTP (
Cache-Control,X-Robots-Tag) →headers() - Error/404 halaman bodies →
ErrorBoundary
3. meta() beats links() ketika data penting.
links() dapat’t see loader data; meta() dapat. So apa pun itu bergantung pada fetched
konten — sebuah dynamic canonical, sebuah data-driven judul — belongs di meta().
4. nesting default adalah “deepest wins, parents dropped.” (terjemahan) “deepest wins, parents dropped.”
decision aturan: apa pun child itu exports meta() harus consciously choose untuk gabungkan
parent meta (matches) atau ini loses ini. Put universal tags (charset/viewport) di
root.tsx JSX di mana merging dapat’t strip them.
5. nyata kode status adalah sebuah SEO fitur, tidak sebuah accident.
throw new Response(..., { status: 404 }) dan throw redirect() adalah bagaimana Remix
menghindari soft-404 / fake-redirect failures dari CSR SPAs. Reach untuk thrown respons
alih-alih rendering sebuah error message di sebuah 200.
Remix SEO — cheat sheet
Per-route exports → apa mereka control
| Export | Controls | Sees loader data? | SEO gunakan |
|---|---|---|---|
meta() | <head> meta/judul/JSON-LD | Ya | judul, deskripsi, OG, JSON-LD, dynamic canonical |
links() | <link> elements | Tidak | Static canonical, favicon, preload |
loader() | server data + status | n/sebuah (ini adalah data) | nyata 404/301, server-hanya fetching |
headers() | respons header HTTP | melalui loaderHeaders | Cache-Control, X-Robots-Tag |
ErrorBoundary | Error/404 halaman body | melalui useRouteError | Usable 404 halaman di-layout |
tag canonical — pick right satu
| perlu | gunakan |
|---|---|
| Static, known di bangun | links() → { rel: "canonical", href } |
| Dynamic (bergantung pada loader data) | meta() → { tagName: "link", rel: "canonical", href } |
kode status dari sebuah loader
throw new Response("Not found", { status: 404 }); // real 404
throw redirect("/new-url/", 301); // real 301Fast facts
- Remix adalah SSR oleh default — konten di awal HTML, Tidak render queue (konfirmasi deployed mode; static prerender/SPA adalah juga configuration options).
- Nested meta: deepest route wins; gabungkan parents melalui
matchesatau lose them. X-Robots-Tagmelaluiheaders()berfungsi untuk crawler itu jangan render.- Remix v2’s APIs digabungkan ke React Router v7 (Dec 2024), sama route API,
package renamed untuk
react-router. React Router adalah now pada v8 (v7 masih security-didukung). Remix 3 (beta) adalah sebuah terpisah, newer kerangka kerja — tidak covered oleh ini halaman. - Resource routes:
sitemap[.xml].tsx,robots[.txt].tsx(brackets escape dot). - Tidak dynamic rendering alat (Rendertron/Prerender.io) needed — atau recommended.
Verify apa crawler sebenarnya menerima
Remix renders pada server, tetapi selalu konfirmasi awal HTML alih-alih post-hydration DOM di DevTools.
periksa mentah server HTML (konten + tags adalah present sebelum JS berjalan)
# Title, meta description, canonical — should all be in the raw response
curl -s https://example.com/blog/my-post/ | grep -iE '<title>|name="description"|rel="canonical"'
# Confirm JSON-LD is in the SSR'd head
curl -s https://example.com/blog/my-post/ | grep -i 'application/ld+json'Konfirmasi nyata HTTP kode status (Tidak soft 404s, nyata redirects)
# A missing page must return 404, not 200
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/blog/does-not-exist/
# A moved URL should return 301/302 with a Location header
curl -sI https://example.com/old-url/ | grep -iE 'HTTP/|location'periksa HTTP-tingkat robots / cache headers dari headers()
curl -sI https://example.com/private-route/ | grep -iE 'x-robots-tag|cache-control'sebuah minimal robots.txt resource route
// app/routes/robots[.txt].tsx
export async function loader() {
return new Response(
`User-agent: *\nAllow: /\nSitemap: https://example.com/sitemap.xml\n`,
{ headers: { "Content-Type": "text/plain" } }
);
} alat untuk auditing sebuah Remix situs
curl/ View Sumber — ground truth untuk apa di awal SSR’d HTML (judul, deskripsi, canonical, JSON-LD) sebelum hydration. jangan trust DevTools Elements alone — ini menampilkan post-JS DOM.- Google Search Console — pemeriksaan URL — see bagaimana Googlebot di-crawl dan dirender sebuah single Remix URL; untuk SSR halaman disajikan dan dirender HTML seharusnya match.
- Rich hasil Test — validate JSON-LD Anda emit melalui
"script:ld+json". - Ahrefs situs Audit — crawl seluruh situs untuk missing/duplicate meta ( nested-meta gabungkan bug surfaces di sini), rusak canonicals, rantai pengalihan, dan depth.
- Screaming Frog SEO Spider — sebuah developer-friendly crawl untuk konfirmasi judul, canonicals, dan kode status di seluruh routes.
vite-bundle-visualizer— inspect client bundles (Remix menggunakan Vite) untuk pertahankan JS lean untuk Core Web Vitals.- Bing Webmaster alat — pemeriksaan URL — verify Bingbot sees SSR’d konten.
Uji pemahaman Anda: Remix SEO
Five quick pertanyaan pada bagaimana Remix menangani SEO. Pick sebuah jawaban untuk setiap, lalu periksa.
Resources worth Anda time
My writing
- JavaScript SEO: sebuah Definitive Guide — rendering, DOM parity, paling-restrictive-directive aturan, dan choosing sebuah rendering mode — kerangka kerja-agnostic background untuk semuanya Remix melakukan oleh default.
- Beginner’s Guide untuk SEO teknis — di mana rendering dan kerangka kerja fit di bigger picture.
My speaking
- Bagaimana Penelusuran berfungsi (SlideShare) — my walkthrough dari crawling, rendering, pengindeksan, dan peringkat. (My standing disclaimer applies: “Ini adalah my understanding dari sistem… tidak going untuk menjadi 100% menyelesaikan atau accurate.” (terjemahan) “ini adalah my understanding dari sistem… tidak going untuk menjadi 100% menyelesaikan atau accurate.”)
«From around the industry
- Remix docs —
metafunction — primary source for per-route metadata andmatchesmerging. - Remix docs —
loaderandheaders— server data, thrown responses, and HTTP headers. - React Router v7 announcement / React Router v8 / React Router docs — the Remix v2 merge, the current v8 release, and where the route API now lives (Remix 3 is a separate, newer product).
- Understand the JavaScript SEO basics (Google) — the rules Remix’s output is judged by: status codes,
<a href>links, SSR guidance. - Dynamic rendering (deprecated) (Google) — why Remix sites never need Rendertron/Prerender.io.
- web.dev — Rendering on the Web — the Chrome team’s CSR/SSR/SSG/hydration explainer; the conceptual backbone for Remix’s server-first model.
- r/TechSEO — the community for framework rendering/indexing debugging. » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian seratus empat puluh lima, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)
Log perubahan
Diperbarui 18 Jul 2026.
Ringkasan editorial dan detail perubahan yang tercatat.Detail perubahan
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
Perbandingan lengkap tidak tersedia — tidak ada cuplikan sebelumnya yang diarsipkan untuk revisi ini.