@qrxcode/js
v0.8.1
Published
QRX flow discovery SDK for JavaScript.
Maintainers
Readme
QRX flow discovery SDK for JavaScript
Discover machine-readable relationships from HTML documents.
QRX resolves normal website URLs, extracts machine-readable declarations from HTML, and returns normalized structural flows.
Applications decide what to do with them.
QRX works with:
- QR code scanners
- pasted links
- shared URLs
- typed URLs
- browser extensions
- app share sheets
- any workflow that receives a URL
A normal QR code still contains a normal URL.
QRX-compatible applications resolve the URL, discover machine-readable flows, and decide what to do next.
Discovery currently supports:
- HTML
<link>declarations - HTML
<meta>declarations
This works especially well with podcast websites, because many podcast sites already expose one or multiple feeds.
With QRX, podcast subscriptions can become as simple and natural as following someone on social media.
Examples of discovered flows:
- Link flows
- Meta flows
Examples of semantic relationships applications can detect:
- Feed links
- QRX links
- Apple Smart App Banner metadata
In QRX, a "flow" is a discovered machine-readable relationship that applications can inspect and act on.
QRX does not replace RSS, existing feed technologies, or existing platform metadata.
QRX helps applications discover and work with them more naturally.
Learn more at https://qrx.dev
0.8.1
Improved HTML discovery performance
QRX now reads HTML progressively and stops after the document head instead of waiting for the full page body.
This significantly improves discovery speed and reliability on large or slow websites while keeping the API and flow behavior unchanged.
Breaking change in 0.7.0
Version 0.7.0 changes QRX flow classification from semantic categories
to structural discovery primitives.
Before 0.7.0, feed and QRX declarations were returned as semantic flow types:
{
flowType: "feed",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml",
source: "html"
}{
flowType: "qrx",
rel: "qrx",
href: "https://example.com/qrx.json",
type: "application/qrx+json",
source: "html"
}Starting from 0.7.0, both are returned as link flows:
{
flowType: "link",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml",
source: "html"
}{
flowType: "link",
rel: "qrx",
href: "https://example.com/qrx.json",
type: "application/qrx+json",
source: "html"
}Core formula:
flowType = structural discovery primitive
rel/type/name/content = semantic meaning from the webMigration:
flow.flowType === "feed"is nowflow.flowType === "link" && flow.rel includes "alternate" && flow.type === "application/rss+xml" | "application/atom+xml" | "application/feed+json".flow.flowType === "qrx"is nowflow.flowType === "link" && flow.rel === "qrx".
This makes QRX closer to how the web already works:
- HTML
<link>becomesflowType: "link". - HTML
<meta>becomesflowType: "meta".
QRX discovers machine-readable relationships from HTML documents.
Applications decide the semantic meaning.
New in 0.7.0
Version 0.7.0 adds HTML <meta> discovery.
The first supported meta declaration is Apple Smart App Banner metadata:
<meta
name="apple-itunes-app"
content="app-id=431946152">Result:
{
flowType: "meta",
name: "apple-itunes-app",
content: "app-id=431946152",
source: "html"
}QRX only discovers this metadata.
QRX does not:
- launch apps
- generate deep links
- validate App Store availability
- check whether the app is installed
- fetch Apple App Store data
- parse Android intent links
- read
assetlinks.json - read
apple-app-site-association - assign trust scores
The consuming application decides whether to open a website, show an install option, open a native app, or use this information as a trust signal.
Previous changes
0.4.0
Version 0.4.0 added QRX link discovery from explicit declarations:
<link
rel="qrx"
type="application/qrx+json"
href="/qrx.json">QRX link discovery requires all of these:
rel="qrx"href- explicit
type
For QRX links, rel must be exactly qrx.
These are valid:
<link rel="qrx" type="application/qrx+json" href="/qrx.json">
<link rel="qrx" type="text/html" href="/qrx-demo.html">
<link rel="qrx" type="application/json" href="/manifest.json">These are not valid QRX link declarations:
<link rel="alternate qrx" type="application/qrx+json" href="/qrx.json">
<link rel="qrx something" type="application/qrx+json" href="/qrx.json">
<link rel="notqrx" type="application/qrx+json" href="/qrx.json">
<link rel="qrx" href="/qrx.json">The type value can be any explicit media type,
not only application/qrx+json.
The package does not fetch or parse QRX payloads. It only discovers the declared link.
0.3.0
Version 0.3.0 introduced a cleanup of feed classification.
Before 0.3.0, RSS, Atom, and JSON Feed were represented as separate
QRX flow types:
{
flowType: "rss",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml"
}Starting from 0.3.0, RSS, Atom, and JSON Feed were represented as the same
semantic QRX flow category:
{
flowType: "feed",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml"
}In 0.7.0, these are now represented structurally as flowType: "link".
Install
npm install @qrxcode/jsUsage
import { resolveQRX } from "@qrxcode/js";
const result = await resolveQRX(
"https://example.com"
);
console.log(result.flows);Example output
[
{
flowType: "link",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml",
source: "html"
},
{
flowType: "link",
rel: "qrx",
href: "https://example.com/qrx.json",
type: "application/qrx+json",
source: "html"
},
{
flowType: "meta",
name: "apple-itunes-app",
content: "app-id=431946152",
source: "html"
}
]Selecting flows
To select all link flows:
import {
resolveQRX,
selectFlowsByFlowType
} from "@qrxcode/js";
const result = await resolveQRX(
"https://example.com"
);
const links = selectFlowsByFlowType(
result.flows,
["link"]
);To select all meta flows:
const metas = selectFlowsByFlowType(
result.flows,
["meta"]
);To select only RSS feed links:
const rssFeeds = result.flows.filter(
(flow) =>
flow.flowType === "link" &&
flow.rel
.toLowerCase()
.split(/\s+/)
.includes("alternate") &&
flow.type === "application/rss+xml"
);To select QRX links:
const qrxLinks = result.flows.filter(
(flow) =>
flow.flowType === "link" &&
flow.rel === "qrx"
);To select Apple Smart App Banner metadata:
const appleAppMeta = result.flows.filter(
(flow) =>
flow.flowType === "meta" &&
flow.name === "apple-itunes-app"
);Supported flow types
linkmeta
Supported link relationships
QRX currently recognizes link flows for:
Feed discovery:
- RSS:
rel="alternate"+type="application/rss+xml" - Atom:
rel="alternate"+type="application/atom+xml" - JSON Feed:
rel="alternate"+type="application/feed+json"
- RSS:
QRX discovery:
rel="qrx"+ explicittype
Supported meta declarations
QRX currently recognizes meta flows for:
Apple Smart App Banner:
name="apple-itunes-app"
Supported discovery methods
Feed link from HTML:
<link
rel="alternate"
type="application/rss+xml"
href="/feed.xml">Result:
{
flowType: "link",
rel: "alternate",
href: "https://example.com/feed.xml",
type: "application/rss+xml",
source: "html"
}QRX link from HTML:
<link
rel="qrx"
type="application/qrx+json"
href="/qrx.json">Result:
{
flowType: "link",
rel: "qrx",
href: "https://example.com/qrx.json",
type: "application/qrx+json",
source: "html"
}Apple Smart App Banner meta from HTML:
<meta
name="apple-itunes-app"
content="app-id=431946152">Result:
{
flowType: "meta",
name: "apple-itunes-app",
content: "app-id=431946152",
source: "html"
}Apple Smart App Banner meta with app argument:
<meta
name="apple-itunes-app"
content="app-id=431946152, app-argument=https://example.com/path">Result:
{
flowType: "meta",
name: "apple-itunes-app",
content: "app-id=431946152, app-argument=https://example.com/path",
source: "html"
}Philosophy
QRX does not change QR codes.
QRX discovers machine-readable web flows from HTML documents.
Applications decide what to do with them.
QRX discovers. Your app decides.
