@crawl-me-maybe/web
v0.0.7
Published
>π¨ This library is under extremely active development, the structure of data is not set in stone, nor are exports in a final stage. I just needed this out of my turborepo folder π.
Readme
@crawl-me-maybe/web
π¨ This library is under extremely active development, the structure of data is not set in stone, nor are exports in a final stage. I just needed this out of my turborepo folder π.
Web utilities and schema markup builders for Sanity driven data.
Installation
npm install @crawl-me-maybe/web
# or
pnpm add @crawl-me-maybe/web
# or
yarn add @crawl-me-maybe/webFeatures
- π― SEO Utilities: Merge page-level and global SEO metadata
- ποΈ Schema Markup Builders: Generate structured data (JSON-LD) for various schema types
- πΌοΈ Image Utilities: Format and optimize Sanity images for schema markup
- π¨ Favicon Generation: Create multi-format favicons from Sanity assets
- π Type-safe: Full TypeScript support with comprehensive type definitions
Quick Start
2. Build SEO Payload
Combine global defaults with page-specific metadata:
import { buildSeoPayload } from '@crawl-me-maybe/web';
const seoData = buildSeoPayload({
globalDefaults: {
siteTitle: 'My Website',
pageTitleTemplate: '{pageTitle} | {siteTitle}',
metaDescription: 'Default site description',
siteUrl: 'https://example.com',
twitterHandle: '@example'
},
pageSeo: {
title: 'About Us',
metadata: {
description: 'Learn more about our company',
canonicalUrl: 'https://example.com/about'
}
},
schemaDefaults: {
organization: {
name: 'Example Company',
url: 'https://example.com'
}
},
pageSchemaType: 'AboutPage'
});
// Use the merged metadata
const { meta, schemas } = seoData;Core Functions
buildSeoPayload(params)
Builds the complete SEO payload for a page, merging global defaults with page-specific metadata.
Parameters:
globalDefaults?: SeoDefaults- Global SEO configurationschemaDefaults?: SchemaDefaults- Global schema markup defaultspageSeo?: PageMetadata- Page-specific metadatapageSchemaType?: string- Schema type (default: "WebPage")extraSchemaData?: Record<string, unknown>- Additional schema dataisHomepage?: boolean- Whether this is the homepage
Returns: { meta: MergedMetadata, schemas: Thing[] | undefined }
SEO Utilities
mergeSeoData(page?, seoDefaults?)
Merges page-level metadata with SEO defaults. Page metadata takes precedence.
createMetaTitle(pageTitle, siteTitle, template)
Generates a meta title using a template.
import { createMetaTitle } from '@crawl-me-maybe/web';
const title = createMetaTitle(
'About Us',
'My Website',
'{pageTitle} | {siteTitle}'
);
// Result: "About Us | My Website"createFavicons(favicon)
Creates multi-format favicons from a Sanity asset. Feed SVG in, generate PNG + SVG.
createSchemaImageObject(image?, fallback?)
Creates a Schema.org ImageObject from a Sanity image asset.
Schema Markup
composeSchema(props)
Composes complete schema markup for a page, returning an array of schema objects to be rendered as JSON-LD.
import { composeSchema } from '@crawl-me-maybe/web';
const schemas = composeSchema({
seo: mergedMetadata,
schemaDefaults: {
organization: {
name: 'Example Company',
url: 'https://example.com'
}
},
type: 'Article',
extra: {
author: [{
name: 'John Doe',
url: 'https://example.com/authors/john-doe'
}],
datePublished: '2025-01-01'
}
});Schema Builders
Individual builder functions for specific schema types:
buildWebPage(props)- Generic webpagebuildWebSite(props)- Website rootbuildArticle(props)- Article/blog postbuildProduct(props)- Product pagebuildEvent(props)- Event pagebuildFAQPage(props)- FAQ pagebuildOrganization(org, defaults, baseUrl)- OrganizationbuildPersonOrOrg(entity, isOrg, baseUrl)- Person or OrganizationbuildAboutPage(props)- About pagebuildContactPage(props)- Contact page
TypeScript Types
All types are fully exported for use in your application:
import type {
// Core types
BuildSeoPayloadParams,
BuildSeoPayloadResult,
// SEO types
SeoDefaults,
PageMetadata,
MergedMetadata,
Favicon,
// Schema types
SchemaDefaults,
SchemaImage,
SchemaAddress,
SchemaGeo,
SchemaAggregateRating,
SchemaPerson,
SchemaOrganization,
SchemaFAQItem,
SchemaSearchAction,
SchemaLocation,
SchemaOffer,
// Image config
SanityImageConfig
} from '@crawl-me-maybe/web';Utility Functions
coalesce(...values)
Returns the first non-null, non-undefined value from the provided arguments.
import { coalesce } from '@crawl-me-maybe/web';
const value = coalesce(undefined, null, 'default', 'fallback');
// Result: "default"Example: Complete Implementation
import {
buildSeoPayload,
type SeoDefaults,
type SchemaDefaults
} from '@crawl-me-maybe/web';
// Define your defaults
const seoDefaults: SeoDefaults = {
siteTitle: 'My Awesome Site',
pageTitleTemplate: '{pageTitle} | {siteTitle}',
metaDescription: 'Welcome to my awesome site',
siteUrl: 'https://awesome.com',
twitterHandle: '@awesome'
};
const schemaDefaults: SchemaDefaults = {
organization: {
name: 'Awesome Company',
url: 'https://awesome.com',
logo: myLogoAsset
}
};
// Build SEO for a page
export async function getPageSeo(page: any) {
return buildSeoPayload({
globalDefaults: seoDefaults,
schemaDefaults,
pageSeo: {
title: page.title,
metadata: {
description: page.description,
canonicalUrl: `https://awesome.com/${page.slug}`
}
},
pageSchemaType: page.schemaType || 'WebPage'
});
}License
MIT
