A pure Dart implementation of Internationalized Resource Identifiers (IRI) as defined in RFC 3987.
This package provides an Iri class that acts as a Unicode-aware wrapper around Dart's native Uri class. It handles the mapping between IRIs and URIs, including automatic Punycode conversion for hostnames and UTF-8 percent-encoding for other components.
- Standard Compliant: Implements the IRI-to-URI mapping and URI-to-IRI conversion rules from RFC 3987.
- Punycode Support: Automatically converts non-ASCII hostnames to Punycode.
- Unicode-Aware: Access components (path, query, fragment, etc.) in their original Unicode form.
- Normalization: Automatically applies NFKC (Normalization Form KC) to all inputs as recommended by RFC 3987 to prevent comparison false-negatives.
- IDNA Separators: Supports international domain separators (
。,.,。) during parsing and conversion. - Mailto Support: Special handling for
mailto:IRIs, ensuring email domain parts are correctly Punycode-encoded. - Familiar API: Mirrors the Dart
Uriclass API, includingresolve,resolveIri, andreplace. - Immutable: The
Iriclass is immutable and supports equality checks.
While this package aims for high compatibility with RFC 3987, there are known areas where the current implementation deviates from the strict specification:
- Robust URI-to-IRI Decoding (RFC 3987 Section 3.2): When converting from a
Urito anIri, the package currently uses standard UTF-8 decoding. If a percent-encoded sequence is invalid UTF-8 (e.g.,%FC), the implementation may throw aFormatExceptioninstead of preserving the percent-encoding as required by the RFC. - Prohibited Characters (RFC 3987 Section 4.1): Certain Unicode characters (like bidirectional control characters
U+202E) are prohibited from appearing directly in an IRI. Currently, these characters are decoded if present in a URI, whereas they should remain percent-encoded. - Bidi Validation (RFC 3987 Section 4.2): The package does not currently perform structural validation of bidirectional IRIs (e.g., ensuring RTL components don't mix directions incorrectly).
These areas may be a part of future updates. For most common use cases involving standard Unicode text in paths and hosts, the package provides a robust experience.
Add iri to your pubspec.yaml dependencies:
dependencies:
iri: ^0.2.0import 'package:iri/iri.dart';
void main() {
// Parse an IRI with Unicode characters
final iri = Iri.parse('http://résumé.example.org/résumé');
print('IRI host: ${iri.host}'); // résumé.example.org
print('IRI path: ${iri.path}'); // /résumé
// Convert to a standard URI for network operations
final uri = iri.toUri();
print('URI host: ${uri.host}'); // xn--rsum-bpad.example.org
print('URI string: $uri'); // http://xn--rsum-bpad.example.org/r%C3%A9sum%C3%A9
}final iri = Iri(
scheme: 'https',
host: 'münchen.test',
path: '/city',
);
print(iri.toUri()); // https://xn--mnchen-3ya.test/city