@arraypress/site-url
v1.0.0
Published
Build absolute and canonical URLs from a base — for SSR/SSG canonical links, OG image URLs, JSON-LD and sitemaps. Zero dependencies.
Maintainers
Readme
@arraypress/site-url
Build absolute and canonical URLs from a base — for SSR/SSG canonical links, OG image URLs, JSON-LD and sitemaps. Zero dependencies.
Works in Node.js, Cloudflare Workers, Deno, Bun, and browsers.
Install
npm install @arraypress/site-urlWhy
In a static/SSR site you constantly need absolute URLs (canonical <link>, og:image, JSON-LD url/@id, sitemap entries). It's tempting to hand-roll them:
const origin = site?.toString().replace(/\/$/, '') ?? '';
const url = `${origin}${path}`; // brittle: no fallback, double-slash bugsThis package does it correctly with the WHATWG URL constructor, takes the base as an argument (so it's framework-agnostic), and falls back gracefully when the base is unset.
Functions
absUrl(path, base?, fallback?)
Resolve path to an absolute URL against base (falling back to fallback). If path is already absolute the base is ignored; if no base is resolvable, path is returned unchanged.
import { absUrl } from '@arraypress/site-url';
absUrl('/og.png', 'https://example.com') // 'https://example.com/og.png'
absUrl('/x', 'https://example.com/') // 'https://example.com/x' (no double slash)
absUrl('https://cdn.test/i.png', 'https://x.com')// 'https://cdn.test/i.png' (already absolute)
absUrl('/x') // '/x' (no base → unchanged)originOf(base?, fallback?)
The origin of base (scheme + host, no trailing slash), or '' if unresolvable.
import { originOf } from '@arraypress/site-url';
originOf('https://example.com/some/path') // 'https://example.com'joinUrl(base, ...segments)
Join a base and path segments with single slashes, skipping empty/nullish segments. No trailing slash is added.
import { joinUrl } from '@arraypress/site-url';
joinUrl('https://x.com/a/', '/b/', 'c') // 'https://x.com/a/b/c'
joinUrl('/types', 'zodiac', 'leo') // '/types/zodiac/leo'
joinUrl('/types/enneagram', 4) // '/types/enneagram/4'stripTrailingSlash(url) / ensureTrailingSlash(url)
Normalise trailing slashes for canonical URLs. ensureTrailingSlash leaves URLs with a query/hash untouched.
import { stripTrailingSlash, ensureTrailingSlash } from '@arraypress/site-url';
stripTrailingSlash('https://x.com/a/') // 'https://x.com/a'
stripTrailingSlash('/') // '/'
ensureTrailingSlash('https://x.com/a') // 'https://x.com/a/'Use with Astro
Astro.site and Astro.url are only available inside .astro frontmatter, so pass them in. Use Astro.site as the base and Astro.url as the fallback, so URLs still resolve in dev/preview where site may be unset.
---
import { absUrl, originOf } from '@arraypress/site-url';
const path = Astro.url.pathname;
const canonical = absUrl(path, Astro.site, Astro.url);
const ogImage = absUrl('/og/home.png', Astro.site, Astro.url);
const origin = originOf(Astro.site, Astro.url);
---
<link rel="canonical" href={canonical} />
<meta property="og:image" content={ogImage} />License
MIT © ArrayPress Limited
