Getting Started
Este contenido aún no está disponible en tu idioma.
-
Install the package
Ventana de terminal npm i @capgo/capacitor-nfcVentana de terminal pnpm add @capgo/capacitor-nfcVentana de terminal yarn add @capgo/capacitor-nfcVentana de terminal bun add @capgo/capacitor-nfc -
Sync with native projects
Ventana de terminal npx cap syncVentana de terminal pnpm cap syncVentana de terminal yarn cap syncVentana de terminal bunx cap sync
Configuration
iOS Configuration
Add the NFC usage description to your Info.plist:
<key>NFCReaderUsageDescription</key><string>This app needs NFC access to read and write tags</string>Enable the Near Field Communication Tag Reading capability in your Xcode project.
Android Configuration
Add the NFC permission to your AndroidManifest.xml:
<manifest> <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="false" /></manifest>Usage
Start Scanning for NFC Tags
import { CapacitorNfc } from '@capgo/capacitor-nfc';
await CapacitorNfc.startScanning({ invalidateAfterFirstRead: false, // Keep session open (iOS) alertMessage: 'Hold a tag near the top of your device.',});
const listener = await CapacitorNfc.addListener('nfcEvent', (event) => { console.log('Tag detected:', event.type); console.log('Tag ID:', event.tag?.id); console.log('NDEF message:', event.tag?.ndefMessage);});Read NFC Tag
await CapacitorNfc.addListener('nfcEvent', (event) => { if (event.tag?.ndefMessage) { event.tag.ndefMessage.forEach(record => { console.log('TNF:', record.tnf); console.log('Type:', record.type); console.log('Payload:', record.payload);
// Decode text record if (record.tnf === 1 && record.type[0] === 0x54) { // Text record const langLen = record.payload[0] & 0x3f; const text = new TextDecoder().decode( new Uint8Array(record.payload.slice(langLen + 1)) ); console.log('Text:', text); } }); }});Write to NFC Tag
// Prepare a text recordconst encoder = new TextEncoder();const langBytes = Array.from(encoder.encode('en'));const textBytes = Array.from(encoder.encode('Hello NFC'));const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, // TNF Well-known type: [0x54], // 'T' for Text id: [], payload, }, ],});
console.log('Tag written successfully');Write URL to NFC Tag
const url = 'https://capgo.app';const urlBytes = Array.from(new TextEncoder().encode(url));
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, // TNF Well-known type: [0x55], // 'U' for URI id: [], payload: [0x01, ...urlBytes], // 0x01 = https:// }, ],});Erase NFC Tag
await CapacitorNfc.erase();console.log('Tag erased');Make Tag Read-Only
await CapacitorNfc.makeReadOnly();console.log('Tag is now read-only');Stop Scanning
await listener.remove();await CapacitorNfc.stopScanning();Check NFC Status
const { status } = await CapacitorNfc.getStatus();console.log('NFC status:', status);// Possible values: 'NFC_OK', 'NO_NFC', 'NFC_DISABLED', 'NDEF_PUSH_DISABLED'
if (status === 'NFC_DISABLED') { // Open system settings await CapacitorNfc.showSettings();}Android Beam (P2P Sharing)
// Share data via Android Beamconst message = { records: [ { tnf: 0x01, type: [0x54], // Text id: [], payload: [/* text record payload */], }, ],};
await CapacitorNfc.share(message);
// Later, stop sharingawait CapacitorNfc.unshare();API Reference
startScanning(options?)
Start listening for NFC tags.
interface StartScanningOptions { invalidateAfterFirstRead?: boolean; // iOS only, defaults to true alertMessage?: string; // iOS only androidReaderModeFlags?: number; // Android only}
await CapacitorNfc.startScanning(options);stopScanning()
Stop the NFC scanning session.
await CapacitorNfc.stopScanning();write(options)
Write NDEF records to the last discovered tag.
interface WriteTagOptions { records: NdefRecord[]; allowFormat?: boolean; // Defaults to true}
interface NdefRecord { tnf: number; // Type Name Format type: number[]; // Record type id: number[]; // Record ID payload: number[]; // Record payload}
await CapacitorNfc.write(options);erase()
Erase the last discovered tag.
await CapacitorNfc.erase();makeReadOnly()
Make the last discovered tag read-only (permanent).
await CapacitorNfc.makeReadOnly();share(options)
Share NDEF message via Android Beam (Android only).
await CapacitorNfc.share({ records: [...] });unshare()
Stop sharing (Android only).
await CapacitorNfc.unshare();getStatus()
Get current NFC adapter status.
const { status } = await CapacitorNfc.getStatus();// Returns: 'NFC_OK' | 'NO_NFC' | 'NFC_DISABLED' | 'NDEF_PUSH_DISABLED'showSettings()
Open system NFC settings.
await CapacitorNfc.showSettings();Events
nfcEvent
Fired when an NFC tag is discovered.
interface NfcEvent { type: 'tag' | 'ndef' | 'ndef-mime' | 'ndef-formatable'; tag?: NfcTag;}
interface NfcTag { id: number[]; techTypes: string[]; type: string | null; maxSize: number | null; isWritable: boolean | null; canMakeReadOnly: boolean | null; ndefMessage: NdefRecord[] | null;}nfcStateChange
Fired when NFC adapter availability changes (Android only).
interface NfcStateChangeEvent { status: NfcStatus; enabled: boolean;}Complete Example
import { CapacitorNfc } from '@capgo/capacitor-nfc';
export class NfcService { private listener: any;
async startReading() { // Check NFC status const { status } = await CapacitorNfc.getStatus();
if (status === 'NO_NFC') { throw new Error('NFC not available on this device'); }
if (status === 'NFC_DISABLED') { await CapacitorNfc.showSettings(); return; }
// Start scanning await CapacitorNfc.startScanning({ invalidateAfterFirstRead: false, alertMessage: 'Ready to scan NFC tags', });
// Listen for tags this.listener = await CapacitorNfc.addListener('nfcEvent', (event) => { this.handleNfcEvent(event); }); }
private handleNfcEvent(event: any) { console.log('NFC Event:', event.type);
if (event.tag?.ndefMessage) { event.tag.ndefMessage.forEach(record => { this.processRecord(record); }); } }
private processRecord(record: any) { // Process text records if (record.tnf === 1 && record.type[0] === 0x54) { const langLen = record.payload[0] & 0x3f; const text = new TextDecoder().decode( new Uint8Array(record.payload.slice(langLen + 1)) ); console.log('Text:', text); }
// Process URI records if (record.tnf === 1 && record.type[0] === 0x55) { const uriCode = record.payload[0]; const uri = new TextDecoder().decode( new Uint8Array(record.payload.slice(1)) ); console.log('URI:', uri); } }
async writeText(text: string) { const encoder = new TextEncoder(); const langBytes = Array.from(encoder.encode('en')); const textBytes = Array.from(encoder.encode(text)); const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, type: [0x54], id: [], payload, }, ], }); }
async stopReading() { if (this.listener) { await this.listener.remove(); } await CapacitorNfc.stopScanning(); }}NDEF Record Types
TNF (Type Name Format)
0x00: Empty0x01: Well-known (e.g., Text, URI)0x02: MIME media type0x03: Absolute URI0x04: External type0x05: Unknown0x06: Unchanged0x07: Reserved
Common Record Types
- Text:
type: [0x54](‘T’) - URI:
type: [0x55](‘U’) - Smart Poster:
type: [0x53, 0x70](‘Sp’)
URI Prefixes
0x00: (no prefix)0x01:https://0x02:https://0x03:http://0x04:https://www.
Best Practices
- Check NFC Status: Always verify NFC is available and enabled
- Handle Permissions: Request NFC permissions appropriately
- Stop Scanning: Always stop scanning when done to save battery
- Error Handling: Wrap NFC operations in try-catch blocks
- Test on Devices: NFC features don’t work on simulators/emulators
Platform Notes
iOS
- Requires iOS 11.0+
- Uses Core NFC framework
- Supports background tag reading (iOS 13+)
- Limited to reading NDEF-formatted tags
- Cannot write tags in background
- Requires NFCReaderUsageDescription in Info.plist
Android
- Requires Android 4.4 (API 19)+
- Uses Android NFC API
- Supports both foreground and background tag reading
- Can write to tags
- Supports Android Beam (P2P) on devices with NFC
- Requires NFC permission in AndroidManifest.xml
Web
- Not supported on web platform