Outcropby Basalt

Guide ·

SEO for a software product in Türkiye: what we do on our Turkish sites

Basalt Studio runs three sites in Turkish: Göçmeden, a board of remote jobs open to people in Türkiye, KahveDrop, a catalogue of Turkish specialty coffee, and Kaç Papel, a price-guessing game. Here is what we do on them for search and AI answers, a terminal check for each step, and what we cannot tell you yet.

Why it differs

Turkish searches are not English searches in translation

People type Turkish with and without its letters. They ask about Turkish tax, payments and prices, which an English page does not answer. And the sources AI answers cite for Turkish questions are often Turkish sites. A software product entering Türkiye with a translated English site misses all three.

Before you start

Set your address once

The checks use curl, grep, sed, awk and perl, which come with macOS and most Linux systems, and work the same in zsh and bash. Set your site’s address once, without a slash at the end. Steps that check one page set that page’s address too.

site=https://example.com

The steps

Six steps on our Turkish sites

Each step has what to do, a check, and what we did on Göçmeden, KahveDrop or Kaç Papel, with the date.

  1. Research keywords in Turkish, with and without Turkish letters

    Do

    Start from what Turkish buyers type, not from a translation of your English keywords. Many type without Turkish letters: ı as i, ş as s, ğ as g, ç as c, ö as o, ü as u. Collect both spellings of each phrase, and watch for short words that mean something else in English: “is” typed for “iş” (job) pulls in “island”.

    Check

    Google’s autocomplete shows what people type. This prints its first five suggestions for a phrase in both spellings. The address is not an official API and can change, so treat it as a quick look, not as keyword data.

    for q in "remote iş" "remote is"; do
      echo "== $q"
      curl -s -G https://suggestqueries.google.com/complete/search -d client=firefox -d hl=tr --data-urlencode "q=$q" |
        perl -CO -MJSON::PP -ne 'print "$_\n" for @{ decode_json($_)->[1] }' | head -5
    done
    On our sites

    Run from Türkiye on 21 Oct 2026, it printed:

    == remote iş
    remote iş ilanları
    remote işler
    remote iş ne demek
    remote iş ilanları istanbul
    remote iş ilanları türkçe
    == remote is
    remote is ilanları türkiye
    remote iş ilanları
    remote island
    remote iş
    remote istanbul

    Göçmeden, our board of remote jobs open to people in Türkiye, shows the same habit in its first Search Console data, read on 20 Oct: its top queries included “yazilim muhendisi is ilani” and “avukat is ilani”, typed without ı, ü or ş. Its page addresses use plain letters, such as /rehber/deel-ile-turkiyeden-calismak/, and its titles keep the Turkish ones.

  2. Write the Turkish pages in Turkish, for Turkish questions

    Do

    Write each page for the question a Turkish reader has, which is often not the one your English page answers. A developer in Türkiye paid by a foreign company asks how to invoice it and what Deel means for their taxes, not what Deel is. Have a native speaker write or edit every page, and mark it as Turkish: lang="tr" on the html element and "inLanguage": "tr" in the structured data.

    Check

    Set the page’s address in page. You want lang="tr" once and inLanguage "tr" in the JSON-LD.

    curl -s "$page" | grep -o -E '<html[^>]* lang="[^"]*"|"inLanguage": ?"[^"]*"' | sed -E 's/<html.* lang=/lang=/' | sort | uniq -c
    On our sites

    Göçmeden’s guides are written in Turkish for those questions: Deel ile Türkiye'den çalışmak (18 Oct) and Yurt dışı şirkete fatura kesmek (19 Oct). On 21 Oct both showed “Son güncelleme: 21 Ekim 2026” (last updated). Kaç Papel, our Turkish price game, got its first structured data on 19 Oct (kacpapel PR #12); before that, 0 of 6 sampled pages had any. Run on kacpapel.app on 21 Oct, the command printed:

       2 "inLanguage":"tr"
       1 lang="tr"
  3. Link the language versions with hreflang: tr and x-default

    Do

    Each page says which language it is in, and where its other versions are, with <link rel="alternate" hreflang="…"> in the head. A Turkish page lists itself as tr. If it has an English version, both pages list both, each pointing at the other. x-default names the version for everyone else. A site only in Turkish can still declare tr and x-default on every page.

    Check

    Set your site’s address in site, without a slash at the end. The first command prints the home page’s hreflang links. The loop fetches every page in the sitemap and counts the pages by the hreflang values they carry; on a few hundred pages it takes a few minutes.

    curl -s "$site/" | grep -o '<link rel="alternate" hreflang="[^"]*" href="[^"]*"'
    curl -s "$site/sitemap.xml" | grep -o '<loc>[^<]*' | sed 's/<loc>//' | while read -r u; do
      curl -s "$u" | grep -o -E 'hreflang="(tr|x-default)"' | sort -u | tr '\n' ' '; echo
    done | sort | uniq -c
    On our sites

    Göçmeden is only in Turkish. It got tr and x-default on every page on 19 Oct (gocmeden PR #43). On 21 Oct, with 295 pages in its sitemap, the commands printed:

    <link rel="alternate" hreflang="tr" href="https://gocmeden.hellobasalt.dev/"
    <link rel="alternate" hreflang="x-default" href="https://gocmeden.hellobasalt.dev/"
     295 hreflang="tr" hreflang="x-default"
  4. Keep descriptions under 160 characters, Turkish words included

    Do

    Turkish words run long, and descriptions built from a job post or a product text run longer. Write the important ones by hand, under 160 characters, and clamp the rest at build time as a safety net.

    Check

    This prints how many pages in the sitemap have a description over 160 characters, counted as characters, not bytes, so ş and ğ count once.

    curl -s "$site/sitemap.xml" | grep -o '<loc>[^<]*' | sed 's/<loc>//' | while read -r u; do
      curl -s "$u" | perl -CS -0777 -ne '($d) = /<meta\s+name="description"\s+content="([^"]*)"/is; $d =~ s/&quot;/"/g; $d =~ s/&amp;/&/g; print length($d), "\n"'
    done | awk '$1 > 160 { n++ } $1 > m { m = $1 } END { print NR, "pages,", n + 0, "over 160, longest", m }'
    On our sites

    Göçmeden has clamped the descriptions of its job pages to 160 characters at build since 19 Oct (gocmeden PR #42). In the sample checked that day, 9 descriptions were too long before the change and 0 after. Its clamp cuts at exactly 160, mid-word when it has to; a cut at the last whole word reads better. On 21 Oct the loop printed:

    295 pages, 0 over 160, longest 160
  5. Find the Turkish sites AI answers cite, and be listed there

    Do

    Ask your Turkish customers’ questions in Turkish, in the assistants they use, and note which sites the answers cite: Turkish career sites, price comparison sites, forums and directories. Those are the listings worth having, ahead of anything in English.

    Check

    Use the method in the AI answer check, in Turkish: a log of who is named and which domains are cited, then a count of the domains.

    On our sites

    Our 19 Oct check asked one customer question for each Basalt product, through web search as a stand-in for the assistants that search. Only 1 of the 9 answers named our product, and it was not one of the Turkish ones. The sources cited across the nine answers included techcareer.net and jobgether.com, both job sites, and cimri.com, a Turkish price comparison site. None of our Turkish sites was named.

  6. Publish a numbers page others can cite

    Do

    A page of numbers only you have, in Turkish, updated on a schedule and dated on the page, with the same numbers in a JSON file under an open licence. Describe it with a Dataset block whose creator and publisher are Organizations; the structured data guide has a check for that. People writing about your market need a source for a number. Make yours the one that is easy to cite.

    Check

    The loop prints the date line of each page; the last two lines should print 200 and a JSON content type.

    for page in https://gocmeden.hellobasalt.dev/rakamlar/ https://kahve.hellobasalt.dev/veri; do
      curl -s "$page" | perl -0777 -pe 's/<(script|style)\b.*?<\/\1>//gis; s/<[^>]+>//g' | grep -o -m 1 -E 'Son güncelleme: [0-9]+ [^ ]+ 20[0-9]{2}'
    done
    curl -s -o /dev/null -w '%{http_code} %{content_type}\n' https://gocmeden.hellobasalt.dev/veri/v1/stats.json
    curl -s -o /dev/null -w '%{http_code} %{content_type}\n' https://kahve.hellobasalt.dev/veri/v1/ozet.json
    On our sites

    Göçmeden’s rakamlar (numbers) page went live on 19 Oct (gocmeden PR #43), with /veri/v1/stats.json under CC BY 4.0. On 21 Oct its description read “bugün 156 remote ilan Türkiye'ye açık”: 156 remote jobs open to people in Türkiye that day. KahveDrop, our catalogue of Turkish specialty coffee, followed with /veri on 20 Oct (tr-coffee-db PR #10): 425 coffees from 39 roasters on 21 Oct, with /veri/v1/ozet.json. The same change put a dated line on 27 of its catalogue landing pages. On 21 Oct the commands printed:

    Son güncelleme: 21 Ekim 2026
    Son güncelleme: 21 Ekim 2026
    200 application/json
    200 application/json

Results

What we cannot tell you yet

Whether these changes bring visitors. When we first read Search Console, on 20 Oct 2026, the hellobasalt.dev property had 32 Google impressions and 0 clicks over its 3-month range, with data only from 17 and 18 Oct. 29 of the 32 were Göçmeden’s. The changes above are days old. Their numbers go on the proof page at 2, 4 and 8 weeks after each change, bad weeks included.