10 altın kural
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">kullan; sabit piksel genişlik verme.htmlöğesine aslaoverflow:hidden+height:100%verme. Kaydırmayı engellemen gerekiyorsa yalnızbody'ye uygula.- Ekranın altına sabitlenmiş (
position:fixed) pencere/form açma; formları sayfa akışında göster. - İki sütunlu ızgaralarda
minmax(0,1fr)kullan, form alanlarınamin-width:0;width:100%ver. - Yüksekliği
window.innerHeightile hesapla veresizeolayında yeniden hesapla. - CSS/JS dosyalarına sürüm eki koy (
app.js?v=…); yoksa kullanıcılar saatlerce eski dosyayı görür. backdrop-filter, ağırfilterve çok katmanlı gölgelerden kaçın.- Renkleri narX tema değişkenlerinden al (
--ix-bg,--ix-text…); koyu tema kendiliğinden çalışır. - Yükleme bitince
iletx.ready()çağır; çağırmazsan kullanıcı açılış ekranında bekler. - Kullanıcı verisini
localStorage'a değililetx.storage'a yaz; cihaz değişince kaybolmaz.
Ekran ve düzen
Ekran ölçüleri
- Hedef genişlik 320–480 px (telefon). Tablet ve web'de içeriği en çok 560–640 px genişlikte ortala (
max-width:560px;margin:0 auto). - Kullanılabilir yükseklik, narX'in üst çubuğu ve sistem çubukları düşüldükten sonra kalan alandır; telefonda genelde 560–760 px. Sabit yükseklik varsayma,
innerHeightkullan. - Sayfa yatay kaydırma üretmemeli:
scrollWidth≤innerWidth. Güvence içinhtml,body{overflow-x:hidden;max-width:100%}. - Alt kenarda çentik ve hareket çubuğu için
padding-bottom:env(safe-area-inset-bottom)ekle. - narX'in ana düğmesini (
iletx.ui.mainButton) kullanıyorsan içeriğin altında en az 96 px boşluk bırak.
Önerilen temel CSS
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html,body{overflow-x:hidden;max-width:100%}
body{margin:0;background:var(--ix-bg);color:var(--ix-text);font:15px/1.45 system-ui,sans-serif;
padding-bottom:calc(96px + env(safe-area-inset-bottom))}
main{max-width:560px;margin:0 auto;padding:12px 14px}
.f2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}
input,select,textarea{width:100%;min-width:0;font:inherit;-webkit-appearance:none;appearance:none}Tam ekran (oyun, harita, çizim) düzeni
- Kaydırmayı
body{overflow:hidden;touch-action:none}ile kapat;html'e dokunma. - Oyun alanını genişliğe ve yüksekliğe sığacak şekilde hesapla:
boyut = min(genişlik, (innerHeight − üst şerit − alt düğmeler) × oran). - Ekranın altına yalnız küçük bir düğme şeridi sabitleyebilirsin; büyük form ya da pencere sabitleme.
- Canvas'ı
devicePixelRatioile ölçekle (bulanık görünmesin).
Formlar ve klavye
- Formu açarken ana içeriği gizleyip formu sayfanın başından göster (ayrı sayfa gibi). Alttan açılan sabit pencere eski WebView'larda klavyenin altında kalır ya da yanlış boyutlanır.
- narX, klavye açılınca mini uygulama alanını küçültür ve odaklanan alanı görünür tutar; ek
scrollIntoViewgerekmez. - Sayı girişinde
inputmode="decimal"/"numeric", tarih içintype="date"kullan; tarih alanını da diğerleri gibi biçimlendir (yükseklik, kenarlık,appearance:none). - Uzun formlarda
max-heightile kısıtlama yapma; sayfa doğal olarak kaysın.
Önbellek ve sürüm
- CDN, CSS/JS/görsel dosyalarını 4 saate kadar önbellekte tutabilir. HTML her açılışta tazelenir.
- Her yayında dosya adresini değiştir:
<script src="app.js?v=2026101801">. narX'te barındırılan uygulamalarda sunucu bu eki kendiliğinden ekler. - SDK'yı her zaman
https://web.narx.tr/sdk/iletx.jsadresinden yükle; kendi kopyanı tutma.
Güvenlik ve ağ
- Uygulaman kendi kökeninde çalışır; narX oturumuna, çerezlerine ve diğer uygulamalara erişemez. Tüm narX işlemleri SDK köprüsünden geçer.
- Adresin HTTPS olmalı (geliştirmede yalnız
http://localhost). - Android'de uygulama yalnız kendi alan adında gezinebilir; başka adresler sistem tarayıcısında açılır. Dış bağlantılar için
iletx.openLink(url)kullan. - Kullanıcı kimliğine istemciden güvenme: sunucunda
initDataimzasını doğrula. eval, uzaktan betik enjeksiyonu ve gizli izleme kodları incelemede reddedilir.
İzinler ve veri
- Yalnız gerçekten kullandığın izinleri bildir (
chat.members,share.chat,contacts.pick,media.pick,location,profile.email). Başvuruda her izin için gerekçe zorunludur. - İzni ilk ihtiyaç anında iste; reddedilirse çökme, anlaşılır bir mesaj göster (
e.code === 'permission_denied'). - Kullanıcının vazgeçmesi hata değildir:
e.code === 'cancelled'durumunda sessizce devam et. - Grupla ortak veride (
iletx.storage+{chat}) her kullanıcı/öğe için ayrı anahtar kullan (ör.rv:<etkinlik>:<kullanıcı>). Tek büyük nesneyi herkes yazarsa değişiklikler birbirini ezer. - Kişisel veriyi üçüncü taraflara gönderme; gizlilik politikanda neyi neden topladığını yaz.
Tasarım
- Dokunma hedefleri en az 44×44 px; oyun kontrolleri için 56–68 px.
- Metin en az 13 px; ana metin 15–16 px.
- Tema değişkenleri:
--ix-bg --ix-card --ix-text --ix-muted --ix-line --ix-brand --ix-lime --ix-navy --ix-danger. Sabit beyaz/siyah kullanma. - Başlığı
iletx.ui.setTitle()ile ver; kendi üst çubuğunu çizme (narX'in çubuğu zaten var). - Birincil eylem için alttaki vurgu renkli ana düğmeyi kullan:
iletx.ui.mainButton.show('Gönder', fn). - Emojiler cihaz yazı tipine göre farklı görünür; kritik bilgi için SVG simge kullan.
Oyunlar için ek kurallar
- Sayfa arka plana geçince (
visibilitychange) oyunu duraklat. - Düğmelerde
pointerdownkullan (gecikme olmaz); basılı tutunca tekrar eden hareket için zamanlayıcı kullan. - Rekoru kişisel depoya, grup sıralamasını sohbet deposuna
hs:<kullanıcı>anahtarıyla yaz. - Skor paylaşımında görsel ekle (
card.image, 1200×630, HTTPS); görselli kartlar çok daha fazla tıklanır.
Sınırlar
| Konu | Sınır |
|---|---|
| Kişisel depo | 1 MB / kullanıcı / uygulama |
| Sohbet (ortak) depo | 2 MB / sohbet / uygulama |
| Depo anahtarı | en çok 64 karakter: harf, rakam, _ . : - |
| Tek seferde yazılan anahtar | en çok 100 |
| Köprü çağrısı | dakikada ~120; kart paylaşımı dakikada 20 |
| Seçilen dosyalar (pick.media) | toplam 10 MB |
| Kart | başlık 120, metin 400, düğme 24 karakter; görsel HTTPS |
| initData geçerliliği | 24 saat |
Sık hatalar ve çözümleri
Aşağıdakilerin hepsi narX'in kendi mini uygulamalarında karşılaşıp çözdüğümüz gerçek sorunlardır.
| Belirti | Neden | Çözüm |
|---|---|---|
| Android’de beyaz ekran; yalnız sabit alt düğmeler görünüyor | html{overflow:hidden;height:100%} — Android WebView kök kaydırıcı kilitlenince içeriği çizmiyor | Kilidi yalnız body’ye uygula; html’e yükseklik/overflow verme |
| Beyaz/boş katman, yalnız bazı telefonlarda | backdrop-filter ya da ağır filtreler | Bu efektleri kaldır; yarı saydam düz renk kullan |
| Alttan açılan form ekranın dibinde ince bir şerit olarak görünüyor | position:fixed alt pencere + eski WebView yükseklik hesabı | Formu sayfa akışında, ana içeriği gizleyerek göster |
| Form klavyenin altında kalıyor | Sabit konumlu pencere / vh birimi | Sayfa akışında form; vh yerine yüzde ya da innerHeight |
| Sayfa sağa kayıyor, kutular ekrandan taşıyor | Izgara sütunu 1fr + alanların varsayılan genişliği | minmax(0,1fr) + input{min-width:0;width:100%} + overflow-x:hidden |
| Tarih/seçim kutusu tasarıma uymuyor | Tarayıcının varsayılan görünümü | appearance:none, aynı yükseklik/kenarlık; seçim için kendi ok simgen |
| Güncelleme yaptım ama telefonda eskisi görünüyor | CDN CSS/JS önbelleği (4 saate kadar) | Dosya adreslerine sürüm eki: ?v=… |
| Uygulama açılış ekranında takılı kalıyor | iletx.ready() çağrılmadı ya da bir hata yüzünden atlandı | Başlangıç kodunu try/catch ile sar; hata durumunda da ready() çağır |
| Grupta biri yazınca diğerinin verisi kayboluyor | Tek anahtarda tüm veriyi herkes yazıyor | Her öğe/kullanıcı için ayrı anahtar; okurken birleştir |
| Karttan açınca grup verisi gelmiyor | Bağlam (iletx.context.conv) kontrol edilmemiş | Kartta param kullan; conv yoksa kullanıcıya grubu açmasını söyle |
| Canvas bulanık | Ekran yoğunluğu (DPR) hesaba katılmamış | canvas.width = css × devicePixelRatio, ctx.setTransform(dpr,0,0,dpr,0,0) |
| Kart sohbette görselsiz | Görsel adresi HTTPS değil ya da erişilemiyor | HTTPS ve herkese açık 1200×630 PNG/JPG |
permission_required hatası | İzin uygulama kaydında bildirilmemiş | İzni uygulama ayarlarına ekle; kullanıcı ilk kullanımda onaylar |
Yayın öncesi kontrol listesi
- ☐ 360×640, 392×800 ve 412×915 ekranlarda yatay kaydırma yok, her şey görünür.
- ☐ Android narX içinde açılıyor (beyaz ekran yok), web'de de açılıyor.
- ☐ Açık ve koyu temada okunur.
- ☐ Klavye açılınca form alanları görünür; uzun form kayar.
- ☐ İzin reddi ve "vazgeç" durumlarında çökme yok.
- ☐
iletx.ready()her yolda çağrılıyor. - ☐ Dosya adreslerinde sürüm eki var.
- ☐ Sohbet dışından açılınca (bağlamsız) anlamlı bir ekran gösteriliyor.
- ☐ Paylaşım kartı sohbette doğru görünüyor, karta dokununca doğru içerik açılıyor.
- ☐ Gizlilik politikası adresi çalışıyor.
Mağaza inceleme ölçütleri
- Çalışırlık: kontrol listesindeki maddeler; ilk açılışta 3 saniye içinde içerik.
- İzinler: her izin gerçekten kullanılıyor ve gerekçesi açık.
- İçerik: yasa dışı, yanıltıcı, kumar ya da yetişkin içerik yok; tescilli marka/isim izinsiz kullanılmıyor.
- Gizlilik: gizlilik politikası var; kişisel veri üçüncü taraflara izinsiz aktarılmıyor.
- Spam: kullanıcı onayı olmadan sohbete mesaj/kart gönderilmiyor; bot bildirimleri makul sıklıkta.
- Reddedilen başvurular gerekçesiyle @botfather üzerinden bildirilir; düzeltip yeniden başvurabilirsin.
SDK başvurusu, initData doğrulama ve sunucu API'si için Geliştiriciler sayfasına ve narX'te @botfather'a bak.