Браузерна інтеграція NFC: читання та запис міток без додатків

Браузерна інтеграція NFC відкриває нові можливості для інвентаризації та автоматизації, але потребує точного налаштування й обробки винятків. Ми розробляємо рішення, які дозволяють читати та записувати NFC-мітки прямо з браузера, без встановлення застосунків. Наша команда реалізує проєкт під ключ — від аудиту до впровадження та подальшої підтримки, забезпечуючи стабільну роботу на сумісних пристроях.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Браузерна інтеграція NFC: читання та запис міток без додатків
Середній
від 1 дня до 3 днів
Часті запитання

Ви розробили PWA для інвентаризації складу. Співробітник підносить телефон до мітки NTAG215 — картка активу підвантажується за секунду. Але половина пристроїв видають помилку: «Web NFC недоступний». Або ваші мітки NTAG213 не вміщують JSON з кількома полями. Web NFC API вирішує ці завдання, але вимагає правильного налаштування та обробки винятків. Ми допоможемо інтегрувати NFC-функціональність у ваш сайт: від простого читання до повноцінної системи запису та синхронізації з API.

Як працює Web NFC API?

Web NFC API надає доступ до NFC-чіпа пристрою з браузера. Він працює тільки з NDEF-сумісними мітками (формат обміну даними NFC). Підтримка обмежена Chrome для Android 89+ (desktop, iOS та інші браузери відсутні). Обов'язково HTTPS і жест користувача (наприклад, натискання кнопки) для першого запуску. Якщо підтримки немає — передбачаємо fallback на QR-коди або ручне введення. Перевірити підтримку можна одним рядком: const isSupported = 'NDEFReader' in window.

Які дані можна зберігати на NFC-мітках?

NDEF-повідомлення може містити одну або кілька записів. Основні типи: text — текст у кодуванні UTF-8 із зазначенням мови; url — URL-адреса; mime — довільні дані (наприклад, JSON); smart-poster — вкладена структура з URL, текстом і дією. На практиці найчастіше використовують JSON для передачі структурованих даних або URL для швидкого переходу. Чим компактніший JSON, тим швидше читання: для зменшення обсягу застосовуйте tree-shake — видаляйте зайві поля.

Порівняння чіпів NFC: який обрати?

Чіп Пам'ять Підходить для Ціна (умовно)
NTAG213 144 байти Один URL або короткий текст Низька
NTAG215 504 байти URL + текст або невеликий JSON Середня
NTAG216 888 байт Великий JSON з кількома полями Вище середньої

NTAG215 у 3,5 рази місткіший за NTAG213, при цьому лише на 20% дорожчий. Для інвентаризації обладнання рекомендуємо NTAG215: він оптимальний за співвідношенням ємність/ціна, дозволяє зберігати JSON з ID, назвою, локацією та часом перевірки. Одна мітка NTAG215 коштує близько $1–1ів, а економія від автоматизації сягає $4.5k–6.5kів на рік.

Типові помилки Web NFC API та їх обробка

Помилка Причина Рішення
NotAllowedError Користувач відхилив дозвіл Показати повідомлення з проханням дозволити NFC
AbortError Користувач натиснув «Скасувати» Просто завершити сценарій
TypeError Невірний формат NDEF-запису Перевірити структуру NDEFMessageInit
NotSupportedError Браузер не підтримує Web NFC Fallback на QR-код або ручне введення

Читання NFC-міток: приклад коду

Для читання створюємо екземпляр NDEFReader, викликаємо scan() і підписуємося на подію reading. При помилці доступу (NotAllowedError) показуємо користувачеві зрозуміле повідомлення.

class NFCReader {
    private reader: NDEFReader | null = null
    private isReading = false

    async startReading(
        onRecord: (record: NFCRecord) => void,
        onError?: (error: Error) => void
    ): Promise<void> {
        if (!('NDEFReader' in window)) {
            throw new Error('Web NFC не підтримується в цьому браузері')
        }

        this.reader = new NDEFReader()
        this.isReading = true

        try {
            await this.reader.scan()
        } catch (err) {
            if ((err as Error).name === 'NotAllowedError') {
                throw new Error('Дозвіл на NFC не надано')
            }
            throw err
        }

        this.reader.addEventListener('reading', (event: NDEFReadingEvent) => {
            console.log(`NFC UID: ${event.serialNumber}`)
            for (const record of event.message.records) {
                onRecord(record)
            }
        })

        this.reader.addEventListener('readingerror', (event) => {
            onError?.(new Error('Помилка читання NFC'))
        })
    }

    stop() {
        this.isReading = false
        this.reader = null
    }
}

Для декодування записів (текст, URL, JSON) використовуйте утиліту:

interface ParsedNFCRecord {
  type: string
  data: string | Record<string, unknown>
}

function parseNFCRecord(record: NDEFRecord): ParsedNFCRecord {
  switch (record.recordType) {
    case 'text': {
      const decoder = new TextDecoder(record.encoding ?? 'utf-8')
      return {
        type: 'text',
        data: decoder.decode(record.data),
      }
    }
    case 'url': {
      const decoder = new TextDecoder()
      return {
        type: 'url',
        data: decoder.decode(record.data),
      }
    }
    case 'mime': {
      if (record.mediaType === 'application/json') {
        const decoder = new TextDecoder()
        try {
          return {
            type: 'json',
            data: JSON.parse(decoder.decode(record.data)),
          }
        } catch {
          return {
            type: 'text',
            data: decoder.decode(record.data)
          }
        }
      }
      return {
        type: record.mediaType ?? 'binary',
        data: '[binary data]',
      }
    }
    case 'smart-poster': {
      return {
        type: 'smart-poster',
        data: 'Smart Poster record'
      }
    }
    default:
      return {
        type: record.recordType,
        data: '[unknown]'
      }
  }
}

Запис на NFC-мітку

Для запису використовуємо NDEFReader.write(). Можна комбінувати URL, текст і JSON:

class NFCWriter {
  async write(data: NFCWriteData): Promise<void> {
    const writer = new NDEFReader()
    const message: NDEFMessageInit = {
      records: this.buildRecords(data),
    }
    await writer.write(message)
    console.log('Запис на мітку виконано')
  }

  private buildRecords(data: NFCWriteData): NDEFRecordInit[] {
    const records: NDEFRecordInit[] = []
    if (data.url) {
      records.push({
        recordType: 'url',
        data: data.url
      })
    }
    if (data.text) {
      records.push({
        recordType: 'text',
        data: data.text,
        lang: 'ru',
      })
    }
    if (data.json) {
      records.push({
        recordType: 'mime',
        mediaType: 'application/json',
        data: new TextEncoder().encode(JSON.stringify(data.json)),
      })
    }
    return records
  }

  async writeWithPassword(message: NDEFMessageInit, password: string): Promise<void> {
    const writer = new NDEFReader()
    await writer.write(message, { overwrite: true, })
  }
}

interface NFCWriteData {
  url?: string
  text?: string
  json?: unknown
}

Реальний кейс: інвентаризація складу

Ми впровадили Web NFC для клієнта з логістики. Кожен стелаж та одиниця обладнання були помічені мітками NTAG215. Співробітник відкриває PWA на Android, натискає «Сканувати», підносить телефон — і додаток автоматично підвантажує картку активу з ERP. Раніше процес займав 3 хвилини ручного введення, тепер — 15 секунд. Швидкість інвентаризації зросла в 12 разів, помилки введення виключені. Економія коштів для клієнта склала понад $4.5k–6.5kів на рік за рахунок зниження простоїв та ручної праці.

function AssetInventory() {
  const [scanned, setScanned] = useState<AssetData | null>(null)
  const [isScanning, setIsScanning] = useState(false)
  const readerRef = useRef<NFCReader | null>(null)

  async function startScan() {
    if (!('NDEFReader' in window)) {
      alert('Web NFC недоступний. Використовуйте Chrome на Android.')
      return
    }
    setIsScanning(true)
    readerRef.current = new NFCReader()
    await readerRef.current.startReading(
      (record) => {
        const parsed = parseNFCRecord(record)
        if (parsed.type === 'json' && isAssetData(parsed.data)) {
          setScanned(parsed.data as AssetData)
          setIsScanning(false)
          readerRef.current?.stop()
        }
      },
      (error) => {
        console.error('NFC error:', error)
        setIsScanning(false)
      }
    )
  }

  function stopScan() {
    readerRef.current?.stop()
    setIsScanning(false)
  }

  return (
    <div>
      {!('NDEFReader' in window) && (
        <div className="bg-yellow-50 border border-yellow-200 rounded p-3 text-sm">
          Web NFC вимагає Chrome на Android
        </div>
      )}
      <button
        onClick={isScanning ? stopScan : startScan}
        className={`w-full py-4 rounded-xl text-lg font-medium ${
          isScanning ? 'bg-red-500 text-white' : 'bg-blue-600 text-white'
        }`}
      >
        {isScanning ? '⏹ Зупинити сканування' : '📡 Сканувати NFC-мітку'}
      </button>
      {isScanning && (
        <div className="text-center py-8 text-gray-500">
          Піднесіть мітку до задньої частини телефону...
        </div>
      )}
      {scanned && (
        <AssetCard asset={scanned} onClose={() => setScanned(null)} />
      )}
    </div>
  )
}

Запис міток при інвентаризації

Для первинного маркування активів використовуємо ту саму бібліотеку запису:

async function tagAsset(assetId: string, assetData: AssetData) {
  const writer = new NFCWriter()
  await writer.write({
    json: {
      id: assetId,
      name: assetData.name,
      location: assetData.location,
      category: assetData.category,
      lastCheck: new Date().toISOString(),
    },
  })
}

Що входить в інтеграцію від нас

  • Аналіз вимог та вибір відповідних чіпів (NTAG213/215/216).
  • Розробка модуля читання/запису з обробкою всіх помилок (NoPermission, AbortError).
  • UI/UX з великими кнопками та зрозумілими інструкціями для мобільних пристроїв.
  • Тестування на реальних мітках у різних умовах (освітлення, кут піднесення).
  • Документація по інтеграції з вашим бекендом (синхронізація даних).
  • Підтримка після запуску (гарантія 3 місяці).

Терміни: від 2 до 5 днів залежно від обсягу робіт (читання — 1-2 дні, читання+запис+синхронізація — 3-5 днів).

Чому обирають нас?

Ми займаємося веб-розробкою більше 5 років, реалізували 50+ проєктів з інтеграцією апаратних API (NFC, Bluetooth, Camera). Гарантуємо, що рішення працюватиме на 95% Android-пристроїв з Chrome. Надаємо демо-стенд для тестування до початку робіт. Замовте інтеграцію Web NFC — зв'яжіться з нами для консультації. Оцінимо ваш проєкт і запропонуємо оптимальне технічне рішення.

Більш детально про Web NFC API читайте в MDN Web NFC API.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060