1import{j as e}from"./vendor-motion-CJ7_hwUm.js";import{r as k}from"./vendor-router-BS3aRNYz.js";import{T as G,a as N,l as y,f as h,I as u,C as $}from"./ToolPageLayout-Cf6CXVSL.js";import{a as T}from"./index-CSy7JWBg.js";import"./ContactSection-BtpFAFdz.js";import"./pricing-IHJO1nJ8.js";const m={slug:"narzedzia/generator-hreflang",pageTitle:"Generator hreflang â tagi wersji jÄzykowych i wpisy sitemap",metaDescription:'Darmowy generator tagów hreflang: dodaj wersje jÄzykowe strony, a otrzymasz komplet wzajemnych tagów link rel="alternate" oraz wpisy do mapy XML â z walidacjÄ
kodów i x-default.',heroKicker:"Darmowe narzÄdzie SEO",heroTitle:["Generator","hreflang."],heroSubtitle:"Strona po polsku, angielsku i niemiecku? Hreflang mówi Google, którÄ
wersjÄ pokazaÄ użytkownikowi w danym kraju â ale wymaga kompletu wzajemnych odwoÅaÅ na każdej wersji. Ten generator buduje je bezbÅÄdnie: tagi do <head> i wpisy do mapy XML.",defaults:{rows:[{lang:"pl",region:"",url:"https://twojafirma.pl/"},{lang:"en",region:"",url:"https://twojafirma.pl/en/"},{lang:"de",region:"",url:"https://twojafirma.pl/de/"}],xDefaultIndex:0},languages:[{code:"pl",label:"polski"},{code:"en",label:"angielski"},{code:"de",label:"niemiecki"},{code:"uk",label:"ukraiÅski"},{code:"cs",label:"czeski"},{code:"sk",label:"sÅowacki"},{code:"fr",label:"francuski"},{code:"es",label:"hiszpaÅski"},{code:"it",label:"wÅoski"},{code:"nl",label:"niderlandzki"},{code:"sv",label:"szwedzki"},{code:"no",label:"norweski"},{code:"da",label:"duÅski"},{code:"lt",label:"litewski"},{code:"ru",label:"rosyjski"}],regions:[{code:"",label:"â bez regionu â"},{code:"PL",label:"Polska"},{code:"GB",label:"Wielka Brytania"},{code:"US",label:"USA"},{code:"DE",label:"Niemcy"},{code:"AT",label:"Austria"},{code:"CH",label:"Szwajcaria"},{code:"UA",label:"Ukraina"},{code:"CZ",label:"Czechy"},{code:"SK",label:"SÅowacja"},{code:"FR",label:"Francja"},{code:"ES",label:"Hiszpania"},{code:"IT",label:"WÅochy"},{code:"NL",label:"Holandia"},{code:"IE",label:"Irlandia"}],seoSections:[{heading:"Jak dziaÅa hreflang i dlaczego tak Åatwo go zepsuÄ?",paragraphs:['Hreflang to adnotacja mówiÄ
ca Google: âta sama treÅÄ istnieje w innych jÄzykach â użytkownikowi z Niemiec pokaż wersjÄ de, Polakowi wersjÄ pl". Bez niej Google potrafi pokazaÄ Niemcowi polskÄ
wersjÄ strony (bo ma mocniejsze sygnaÅy) albo potraktowaÄ wersje jÄzykowe jako duplikaty.',"NajczÄstszy bÅÄ
d to brak wzajemnoÅci: jeÅli strona polska wskazuje angielskÄ
, to angielska MUSI wskazywaÄ polskÄ
â i obie muszÄ
wskazywaÄ także same siebie. Google ignoruje tagi bez potwierdzenia zwrotnego. Dlatego ten generator tworzy jeden komplet tagów, identyczny dla każdej wersji jÄzykowej: wklejasz ten sam blok do <head> każdej z nich i wzajemnoÅÄ jest zapewniona z definicji.",'Druga puÅapka to kody: hreflang używa kodów jÄzyka ISO 639-1 (pl, en, de) z opcjonalnym kodem kraju ISO 3166-1 (en-GB, de-AT). Popularne bÅÄdy â âen-UK" zamiast âen-GB", âcz" zamiast âcs", sam kod kraju bez jÄzyka â sprawiajÄ
, że Google tag po cichu ignoruje. Generator waliduje kody, zanim cokolwiek wygenerujesz.']},{heading:"Tagi w <head> czy w mapie XML â co wybraÄ?",paragraphs:["Google akceptuje hreflang w trzech miejscach: tagach <link> w <head>, nagÅówkach HTTP i mapie strony XML. W praktyce wybierasz miÄdzy pierwszym a ostatnim:"],tips:[{icon:"code",title:"Tagi <link> â proÅciej",text:"NajÅatwiejsze do wdrożenia (wklejasz w szablon strony) i do debugowania (widaÄ w źródle). Minus: powiÄkszajÄ
każdy dokument HTML â przy kilkunastu wersjach jÄzykowych robi siÄ z tego zauważalny narzut."},{icon:"account_tree",title:"Sitemap XML â czyÅciej przy skali",text:"Wpisy xhtml:link w mapie strony nie obciÄ
żajÄ
HTML-a i Åatwiej nimi zarzÄ
dzaÄ centralnie â naturalny wybór dla sklepów i serwisów z wieloma rynkami."},{icon:"public",title:"x-default dla reszty Åwiata",text:"Wersja x-default trafia do użytkowników, których jÄzyk nie pasuje do żadnej wersji. Zwykle wskazuje siÄ wersjÄ angielskÄ
albo stronÄ wyboru jÄzyka â generator pozwala oznaczyÄ jÄ
jednym klikniÄciem."},{icon:"rule",title:"Jedno miejsce, nie dwa",text:"Wybierz tagi ALBO sitemap â duplikowanie hreflang w obu miejscach utrudnia utrzymanie i grozi sprzecznymi sygnaÅami po pierwszej zmianie adresów."}]}],faqHeading:"Pytania o hreflang",faqItems:[{question:"Czy hreflang jest potrzebny, jeÅli strona ma tylko polskÄ
wersjÄ?",answer:'Nie. Hreflang ma sens dopiero przy co najmniej dwóch wersjach jÄzykowych lub regionalnych tej samej treÅci. Dla jednojÄzycznej strony wystarczy poprawny atrybut lang w znaczniku <html> (np. lang="pl"). Hreflang âna zapas" niczego nie poprawia.'},{question:'Czym różni siÄ hreflang="en" od hreflang="en-GB"?',answer:'Sam kod jÄzyka (en) celuje we wszystkich anglojÄzycznych użytkowników. Kod z regionem (en-GB) â tylko w tych z Wielkiej Brytanii. Regionów używaj, gdy naprawdÄ masz osobne treÅci dla rynków (inne ceny, waluty, oferta): np. de-DE i de-AT. JeÅli masz jednÄ
wersjÄ angielskÄ
dla caÅego Åwiata â użyj samego âen", nie âen-US".'},{question:"Co to jest x-default i czy muszÄ go dodawaÄ?",answer:"X-default wskazuje wersjÄ dla użytkowników, których jÄzyk nie pasuje do żadnej zadeklarowanej wersji â na przykÅad Francuza na stronie dostÄpnej po polsku i angielsku. Nie jest obowiÄ
zkowy, ale Google go zaleca. Zwykle wskazuje wersjÄ angielskÄ
lub stronÄ wyboru jÄzyka. Bez x-default Google sam wybierze wersjÄ, niekoniecznie trafnie."},{question:"Dlaczego Google ignoruje moje tagi hreflang?",answer:'Trzy najczÄstsze powody: brak wzajemnoÅci (wersja A wskazuje B, ale B nie wskazuje A â takie tagi sÄ
pomijane), bÅÄdne kody (âen-UK", âcz", sam kod kraju) oraz adresy niedostÄpne dla robota (przekierowania, noindex, blokada w robots.txt). Ten generator eliminuje dwa pierwsze; trzeci sprawdzisz testerem robots.txt obok.'}],relatedLinks:[{to:"/narzedzia",label:"Wszystkie darmowe narzÄdzia SEO"},{to:"/narzedzia/tester-robots",label:"Tester robots.txt"},{to:"/narzedzia/generator-schema",label:"Generator schema.org (JSON-LD)"},{to:"/blog/audyt-strony-internetowej",label:"Audyt strony internetowej â przewodnik"},{to:"/audyt",label:"BezpÅatny audyt strony"}],auditCta:{kicker:"Wersje jÄzykowe to dopiero poczÄ
tek",heading:`Upewnij
1siÄ, że Google widzi 2TwojÄ stronÄ tak, jak chcesz.`,text:"Hreflang, indeksacja, dane strukturalne, szybkoÅÄ â bezpÅatny audyt sprawdzi techniczne fundamenty Twojej strony w 30 sekund i wskaże, co wymaga uwagi."}},b=n=>n.region?`${n.lang}-${n.region}`:n.lang,L=(n,l)=>{const t=[],c=new Map;n.forEach((d,p)=>{const s=b(d);if(!d.url.trim()){t.push({type:"error",msg:`Wiersz ${p+1}: brak adresu URL.`});return}try{const w=new URL(d.url.trim());if(w.protocol!=="https:"&&w.protocol!=="http:")throw new Error}catch(w){t.push({type:"error",msg:`Wiersz ${p+1}: adres musi byÄ peÅnym URL-em (z https://).`})}c.has(s)&&t.push({type:"error",msg:`Kod ${s} wystÄpuje ${c.get(s)+1}. raz â każda wersja jÄzykowa musi mieÄ unikalny kod.`}),c.set(s,(c.get(s)||0)+1)});const i=n.map(d=>d.url.trim()).filter(Boolean);return new Set(i).size!==i.length&&t.push({type:"warn",msg:"Ten sam URL wystÄpuje w kilku wierszach â zwykle każda wersja jÄzykowa ma osobny adres."}),i.some(d=>d.startsWith("http://"))&&t.push({type:"warn",msg:"CzÄÅÄ adresów używa http:// â hreflang powinien wskazywaÄ docelowe (https) wersje."}),l==null&&t.push({type:"warn",msg:"Brak wersji x-default â Google zaleca wskazaÄ wersjÄ domyÅlnÄ dla pozostaÅych jÄzyków."}),t},R=(n,l)=>{const t=n.filter(s=>s.url.trim()),c=t.map(s=>`<link rel="alternate" hreflang="${b(s)}" href="${s.url.trim()}" />`);l!=null&&t[l]&&c.push(`<link rel="alternate" hreflang="x-default" href="${t[l].url.trim()}" />`);const i=c.join(` 3`),p=`<?xml version="1.0" encoding="UTF-8"?> 4<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" 5 xmlns:xhtml="http://www.w3.org/1999/xhtml"> 6${t.map(s=>{const w=[...t.map(j=>` <xhtml:link rel="alternate" hreflang="${b(j)}" href="${j.url.trim()}"/>`),...l!=null&&t[l]?[` <xhtml:link rel="alternate" hreflang="x-default" href="${t[l].url.trim()}"/>`]:[]].join(` 7`);return` <url> 8 <loc>${s.url.trim()}</loc> 9${w} 10 </url>`}).join(` 11`)} 12</urlset>`;return{head:i,sitemap:p}},E=()=>{const[n,l]=k.useState(m.defaults.rows),[t,c]=k.useState(m.defaults.xDefaultIndex),[i,d]=k.useState("head"),p=k.useRef(!1),s=()=>{p.current||(p.current=!0,T("tool_use",{tool:"generator-hreflang"}))},w=(a,r,o)=>{s(),l(z=>z.map((f,v)=>v===a?{...f,[r]:o}:f))},j=()=>l(a=>[...a,{lang:"en",region:"",url:""}]),S=a=>{l(r=>r.filter((o,z)=>z!==a)),c(r=>r===a?null:r>a?r-1:r)},g=L(n,t),x=R(n,t),C=g.some(a=>a.type==="error");return e.jsx(G,{data:m,children:e.jsxs("div",{className:"grid lg:grid-cols-2 gap-6 items-start",children:[e.jsxs(N,{children:[e.jsxs("div",{className:"hidden md:grid grid-cols-[1fr_1fr_2fr_60px_36px] gap-3 px-1 mb-2",children:[e.jsx("span",{className:y,children:"JÄzyk"}),e.jsx("span",{className:y,children:"Region"}),e.jsx("span",{className:y,children:"Adres URL wersji"}),e.jsx("span",{className:y,children:"x-def."}),e.jsx("span",{})]}),e.jsx("div",{className:"space-y-3",children:n.map((a,r)=>e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-[1fr_1fr_2fr_60px_36px] gap-3 items-center",children:[e.jsx("select",{className:`${h} cursor-pointer`,value:a.lang,onChange:o=>w(r,"lang",o.target.value),"aria-label":"JÄzyk",children:m.languages.map(o=>e.jsxs("option",{value:o.code,style:{background:"#0a0f1e"},children:[o.code," â ",o.label]},o.code))}),e.jsx("select",{className:`${h} cursor-pointer`,value:a.region,onChange:o=>w(r,"region",o.target.value),"aria-label":"Region",children:m.regions.map(o=>e.jsx("option",{value:o.code,style:{background:"#0a0f1e"},children:o.code?`${o.code} â ${o.label}`:o.label},o.code))}),e.jsx("input",{className:`${h} col-span-2 md:col-span-1 font-mono !text-xs`,placeholder:"https://twojafirma.pl/en/",value:a.url,onChange:o=>w(r,"url",o.target.value),"aria-label":"Adres URL wersji jÄzykowej"}),e.jsx("label",{className:"flex items-center justify-center cursor-pointer",title:"Wersja x-default",children:e.jsx("input",{type:"radio",name:"xdefault",className:"accent-[#2b6cee] w-4 h-4 cursor-pointer",checked:t===r,onChange:()=>{s(),c(r)}})}),e.jsx("button",{type:"button",onClick:()=>S(r),"aria-label":"UsuÅ wiersz",className:"flex items-center justify-center w-9 h-9 rounded-lg text-gray-600 hover:text-red-400 hover:bg-white/[0.04] transition-colors cursor-pointer",children:e.jsx(u,{name:"close",className:"text-[18px]"})})]},r))}),e.jsxs("button",{type:"button",onClick:j,className:"mt-4 inline-flex items-center gap-1.5 px-4 py-2 rounded-full text-xs font-bold text-primary transition-colors hover:bg-primary/10 cursor-pointer",style:{border:"1px solid rgba(43,108,238,0.35)"},children:[e.jsx(u,{name:"add",className:"text-[16px]"})," Dodaj wersjÄ jÄzykowÄ "]}),g.length>0&&e.jsx("div",{className:"mt-4 space-y-1.5",children:g.map((a,r)=>
12e.jsxs("p",{className:`text-xs flex items-start gap-1.5 ${a.type==="error"?"text-red-400":"text-amber-400"}`,children:[e.jsx(u,{name:a.type==="error"?"error":"warning",className:"text-[14px] mt-0.5 shrink-0"}),a.msg]},r))}),!C&&n.some(a=>a.url.trim())&&e.jsxs("p",{className:"mt-4 text-xs font-bold text-emerald-400 flex items-center gap-1.5",children:[e.jsx(u,{name:"check_circle",className:"text-[14px]"}),"Komplet wzajemnych odwoÅaÅ â ten sam blok wklej na KAÅ»DEJ wersji jÄzykowej."]})]}),e.jsxs(N,{children:[e.jsx("div",{className:"flex items-center gap-2 mb-4",children:[{id:"head",label:"Tagi <head>",icon:"code"},{id:"sitemap",label:"Sitemap XML",icon:"account_tree"}].map(a=>e.jsxs("button",{type:"button",onClick:()=>d(a.id),className:"inline-flex items-center gap-1.5 px-4 py-2 rounded-full text-xs font-bold transition-colors cursor-pointer",style:i===a.id?{background:"rgba(43,108,238,0.15)",color:"#93c5fd",border:"1px solid rgba(43,108,238,0.4)"}:{background:"transparent",color:"#6b7280",border:"1px solid rgba(255,255,255,0.08)"},children:[e.jsx(u,{name:a.icon,className:"text-[14px]"}),a.label]},a.id))}),e.jsx("pre",{className:"rounded-xl px-4 py-3 text-xs font-mono leading-relaxed text-gray-300 overflow-x-auto max-h-[380px] overflow-y-auto",style:{background:"#060a14",border:"1px solid rgba(255,255,255,0.06)"},children:x[i]||"â uzupeÅnij wersje jÄzykowe po lewej â"}),e.jsx("div",{className:"mt-4",children:e.jsx($,{text:x[i],label:i==="head"?"Kopiuj tagi":"Kopiuj sitemap",onCopy:()=>T("tool_copy",{tool:"generator-hreflang",format:i})})})]})]})})};export{E as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.