Skip to content

sarfarajey/web-utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

@sarfarajey/web-utils

Browser/SSR utility belt for Astro and React projects. Three focused modules, zero runtime dependencies.

Install

npm install @sarfarajey/web-utils

Theme Management

Full light/dark/device theme system with localStorage persistence, OS preference detection, and cross-tab sync.

import {
  applyThemeMode,
  getPreferredThemeMode,
  persistThemeMode,
  subscribeToSystemThemeChanges,
  subscribeToThemeStorage,
} from '@sarfarajey/web-utils';

// Read and apply the stored (or document-embedded) theme on load
const mode = getPreferredThemeMode();   // 'light' | 'dark' | 'device'
applyThemeMode(mode);                   // sets data-theme-mode, .dark class, color-scheme

// Persist a user selection
function onThemeChange(selected: 'light' | 'dark' | 'device') {
  persistThemeMode(selected);
  applyThemeMode(selected);
}

// React to OS preference changes when mode === 'device'
const unsubOS = subscribeToSystemThemeChanges(() => applyThemeMode(getPreferredThemeMode()));

// Sync across tabs
const unsubStorage = subscribeToThemeStorage((mode) => applyThemeMode(mode));

DOM side-effects of applyThemeMode(mode):

Attribute / property Value
html[data-theme-mode] 'light' | 'dark' | 'device'
html[data-theme-resolved] 'light' | 'dark'
html.classList 'dark' class added/removed
html.style.colorScheme 'light' | 'dark'

Safe Redirect Sanitization

Prevent XSS and open-redirect attacks when sending users to a post-login destination.

import { sanitizeRedirectPath, getPostAuthRedirect } from '@sarfarajey/web-utils';

// On a sign-in page: ?redirect=/dashboard/
const destination = getPostAuthRedirect(window.location.search, '/home/');
// Validates the path, blocks external URLs, // prefixes, backslash bypasses, and /auth/* loops.

// Or validate raw values directly:
sanitizeRedirectPath('/dashboard/')          // → '/dashboard/'
sanitizeRedirectPath('https://evil.com')    // → null
sanitizeRedirectPath('//evil.com')          // → null
sanitizeRedirectPath('/auth/reset')         // → null  (auth prefix blocked)

Environment Detection

Distinguish 'development' / 'preview' / 'production' from hostname — works in browser and SSR.

import { configureEnv, getEnvironment, isCurrentEnv } from '@sarfarajey/web-utils';

// Call once at app bootstrap
configureEnv({
  productionHosts: ['example.com', 'www.example.com'],
  previewHosts: ['preview.example.com'],
});

getEnvironment(); // 'development' | 'preview' | 'production'

// Guard records that belong to a specific environment
isCurrentEnv(record.environment); // true when record.environment matches current env

localhost and 127.0.0.1 are always 'development'. Cloudflare Pages *.pages.dev aliases are always 'preview'.

License

MIT

About

Browser/SSR utility belt: theme management, safe redirects, environment detection — zero dependencies

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors