Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@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-url

Why

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 bugs

This 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

About

Build absolute and canonical URLs from a base — for SSR/SSG canonical links, OG images, JSON-LD and sitemaps. Zero dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages