Get the parsed SHL object from the SHL URI.
Returns the SHL instance created from parsing the SHL URI provided to the constructor. Use this to access SHL properties like expiration, flags, and manifest URL.
SHL instance with parsed payload data
Create an SHL viewer.
The viewer can be created with or without an initial SHL URI. If no URI is provided, you can parse one later using the shl getter after creating a viewer with a URI.
Optional
fetch?: (url: string, options?: RequestInit) => Promise<Response>Optional fetch implementation for network requests. Defaults to global fetch. Useful for testing or custom network handling.
SHL URI to parse.
Supports both bare URIs (shlink:/...
) and viewer-prefixed URIs (https://viewer.example/#shlink:/...
)
Fetch and decrypt all files from a SHL manifest.
This method processes each file descriptor in the manifest, either decrypting embedded files directly or fetching and decrypting location-based files. It validates that the decrypted content type matches the manifest descriptor.
SHL manifest containing file descriptors
Promise resolving to array of decrypted file objects with content
and contentType
SHLManifestError When content type mismatch occurs
SHLNetworkError When file fetching fails
SHLDecryptionError When file decryption fails
Fetch a manifest from the given URL.
Makes a POST request to the manifest URL with a JSON body containing recipient information and optional passcode/embedding preferences. Handles HTTP error responses and validates the returned manifest structure.
Optional
embeddedLengthMax?: numberOptional preference for embedded file size limit
Optional
passcode?: stringOptional passcode for P-flagged SHLs
Recipient identifier for the manifest request
Manifest URL from SHL payload
Promise resolving to validated manifest object (SHLManifestV1)
SHLInvalidPasscodeError When server returns 401 (invalid/missing passcode)
SHLManifestNotFoundError When server returns 404 (manifest not found)
SHLManifestRateLimitError When server returns 429 (rate limited)
SHLNetworkError When other HTTP errors occur or network fails
SHLManifestError When manifest response is not valid JSON or has invalid structure
const viewer = new SHLViewer({ shlinkURI: 'shlink:/...' });
const manifest = await viewer.fetchManifest({
url: viewer.shl.url,
recipient: 'Dr. Smith - General Practice',
passcode: 'secret123', // if P flag is set
embeddedLengthMax: 8192
});
console.log(`Manifest contains ${manifest.files.length} files`);
Parse decrypted files into structured SMART Health Cards and FHIR resources.
This method processes the decrypted file content based on their content types, creating SHC objects from application/smart-health-card files and parsing FHIR resources from application/fhir+json files.
Array of decrypted files with metadata
Optional
shcReaderConfig: SHCReaderConfigParamsOptional configuration for SMART Health Card verification
Promise resolving to structured content organized by type (smartHealthCards
, fhirResources
)
SHLInvalidContentError When file content is not valid JSON or invalid SHC/FHIR resource
const viewer = new SHLViewer({ shlinkURI: 'shlink:/...' });
const manifest = await viewer.fetchManifest({ url: viewer.shl.url, recipient: 'Dr. Smith' });
const decryptedFiles = await viewer.decryptFiles(manifest);
const { smartHealthCards, fhirResources } = await viewer.parseDecrypted(
decryptedFiles,
{ publicKey: myPublicKey }
);
console.log(`Found ${smartHealthCards.length} health cards and ${fhirResources.length} FHIR resources`);
Resolve a SHL URI by fetching and decrypting all referenced content.
This method performs the complete SHL resolution workflow:
Optional
embeddedLengthMax?: numberOptional preference for embedded vs location files. Files smaller than this size (in bytes) will be embedded in manifest response. Servers may honor or cap this value per request. Typical values: 4096-16384.
Optional
passcode?: stringOptional passcode for P-flagged SHLs. Required when SHL has 'P' flag, ignored otherwise.
Required recipient identifier sent in manifest request. This should identify the requesting user/system (e.g., "Dr. Smith", "Patient Portal")
Optional
shcReaderConfig?: SHCReaderConfigParamsOptional configuration for SMART Health Card verification (e.g. public key)
Promise resolving to structured content with manifest and decrypted files (SHLResolvedContent)
SHLViewerError When recipient is not a non-empty string
SHLExpiredError When SHL has expired (exp field < current time)
SHLInvalidPasscodeError When P-flagged SHL requires passcode but none provided, or passcode is incorrect
SHLManifestNotFoundError When manifest URL returns 404
SHLManifestRateLimitError When requests are rate limited (429)
SHLNetworkError When network requests fail
SHLDecryptionError When file decryption fails
SHLManifestError When manifest structure is invalid or file content is malformed
SHLInvalidContentError When file content is not valid JSON or invalid SHC/FHIR resource
const viewer = new SHLViewer({ shlinkURI: 'shlink:/...' });
try {
const resolved = await viewer.resolveSHL({
recipient: 'Dr. Smith - General Practice',
passcode: viewer.shl.requiresPasscode ? 'user-provided-passcode' : undefined,
embeddedLengthMax: 8192 // Prefer embedding files under 8KB
});
// Process SMART Health Cards
for (const shc of resolved.smartHealthCards) {
console.log('SHC issuer:', shc.issuer);
console.log('SHC data:', shc.fhirBundle);
}
// Process FHIR resources
for (const resource of resolved.fhirResources) {
console.log('Resource type:', resource.resourceType);
}
} catch (error) {
if (error instanceof SHLExpiredError) {
console.error('SHL has expired');
} else if (error instanceof SHLInvalidPasscodeError) {
console.error('Invalid or missing passcode');
}
// Handle other error types...
}
SHL Viewer handles parsing and resolving SMART Health Links.
This class processes SHL URIs and fetches/decrypts the referenced content. It supports both embedded and location-based file descriptors, handles passcode authentication, and validates manifest structures according to the SMART Health Links specification.
The viewer automatically handles:
Example