@netgen/storyblok-siteaccess
v0.1.10
Published
Generic siteaccess management for multi-market, multi-language Storyblok websites
Readme
@netgen/storyblok-siteaccess
Generic siteaccess management for multi-market, multi-language Storyblok websites.
Features
- Generic & Type-safe: Works with any market/language structure using TypeScript generics
- URL Generation: Convert between Storyblok paths, URLs, and pathnames
- Multi-market Support: Handle multiple markets with different languages
- Alternate Language Management: Generate language/market alternatives for SEO
- Framework Agnostic Core: Works with any framework, with optional React hooks
- Environment Management: Support for different environments (dev, prod, etc.)
- Next.js Integration: Built-in utilities for Next.js routing and redirects
- Internationalization: Generate next-intl routing configurations automatically
Installation
npm install @netgen/storyblok-siteaccessBasic Usage
1. Define Your Types
// Your project types
export enum Market {
us = 'us',
uk = 'uk',
de = 'de'
}
export enum Language {
en = 'en',
de = 'de'
}
// Type your configurations
export type ProjectSiteaccessConfig = SiteaccessConfig<Market, Language>;
export type ProjectEnvironmentConfig = EnvironmentConfig<Market, Language>;2. Create Configuration
import { SiteaccessResolver, Siteaccess } from '@netgen/storyblok-siteaccess';
const environmentConfig: ProjectEnvironmentConfig = {
siteaccess: [
{
host: 'example.com',
locale: 'en',
market: Market.us,
language: Language.en,
storyblokFolderPrefix: 'us',
storyblokVisualEditorPrefix: 'us',
},
{
host: 'example.de',
locale: 'de',
market: Market.de,
language: Language.de,
storyblokFolderPrefix: 'de',
storyblokVisualEditorPrefix: 'de',
}
],
marketConfigs: {
[Market.us]: {
primaryLanguage: Language.en,
tosStoryblokPath: 'terms-of-service'
},
[Market.de]: {
primaryLanguage: Language.de,
tosStoryblokPath: 'nutzungsbedingungen'
}
},
siteinfoIds: {
[Market.us]: 'us-siteinfo-id',
[Market.de]: 'de-siteinfo-id'
},
partnersFolderStoryblokPrefix: 'partners',
hosts: [
{ host: 'example.com', defaultLocale: 'en' },
{ host: 'example.de', defaultLocale: 'de' }
]
};
// Create resolver
const siteaccessResolver = new SiteaccessResolver(
environmentConfig.siteaccess,
environmentConfig
);3. Use Siteaccess
// Resolve configuration
const config = siteaccessResolver.resolveByLocale({ locale: 'en' });
// Create siteaccess instance
const siteaccess = new Siteaccess(config, environmentConfig);
// Generate URLs
const url = siteaccess.getUrl({ storyblokPath: 'about' });
// Result: 'https://example.com/about'
const storyblokPath = siteaccess.getStoryblokPath({ pathname: '/about' });
// Result: 'us/about'React Integration
Basic Hook Usage
import { useSiteaccess } from '@netgen/storyblok-siteaccess';
function MyComponent() {
const siteaccess = useSiteaccess(siteaccessConfig, environmentConfig);
const aboutUrl = siteaccess.getUrl({ storyblokPath: 'about' });
return <a href={aboutUrl}>About Us</a>;
}Create Project-Specific Hook
import { createSiteaccessHook } from '@netgen/storyblok-siteaccess';
// Create your typed hook
export const useProjectSiteaccess = createSiteaccessHook<Market, Language>(
() => getCurrentSiteaccessConfig(),
() => environmentConfig
);
// Use in components
function MyComponent() {
const siteaccess = useProjectSiteaccess();
// Fully typed with your Market and Language enums
}Advanced Features
Market Alternates
const alternates = siteaccess.getMarketAlternates(
Object.values(Market), // All available markets
{ storyblokAlternates: story.alternates }
);
// Result: Array of alternate URLs for different marketsLanguage Validation
const isValid = siteaccess.isStoryLanguageTranslationValid(story);
// Checks if the current language has a valid translationStoryblok API Integration
const storyblokLanguage = siteaccess.getStoryblokLanguage();
// Returns 'default' for primary language, actual language code otherwise
const apiLanguage = siteaccess.getLanguageForStoryblok();
// Returns undefined for primary language, language code otherwiseClient/Server Resolution
Next.js Example
import {
createLocaleBasedClientResolver,
createLocaleBasedServerResolver,
createUniversalSiteaccessResolver
} from '@netgen/storyblok-siteaccess';
import { useLocale } from 'next-intl';
import { getLocale } from 'next-intl/server';
// Create resolvers
const clientResolver = createLocaleBasedClientResolver(
useLocale,
(locale) => siteaccessResolver.resolveByLocale({ locale })
);
const serverResolver = createLocaleBasedServerResolver(
getLocale,
(locale) => siteaccessResolver.resolveByLocale({ locale })
);
const universalResolver = createUniversalSiteaccessResolver(
clientResolver,
serverResolver
);
// Use in your app
export const getCurrentSiteaccessConfig = {
client: universalResolver.client,
server: universalResolver.server
};API Reference
Classes
Siteaccess<TMarket, TLanguage>: Main class for URL generation and path conversionSiteaccessResolver<TMarket, TLanguage>: Resolves siteaccess configurations based on various criteria
Types
SiteaccessConfig<TMarket, TLanguage>: Configuration for a single siteaccessEnvironmentConfig<TMarket, TLanguage>: Complete environment configurationAlternateStory<TMarket, TLanguage>: Language/market alternate informationSiteaccessInputType: Input union type for path conversion methods
Hooks
useSiteaccess(): React hook for creating Siteaccess instancescreateSiteaccessHook(): Factory for creating project-specific hooks
Resolvers
createClientSiteaccessResolver(): Create client-side resolvercreateServerSiteaccessResolver(): Create server-side resolvercreateUniversalSiteaccessResolver(): Create universal resolver
Migration from Project-Specific Implementation
- Extract your types: Move Market/Language enums to your project
- Update imports: Import from
@netgen/storyblok-siteaccess - Add type parameters: Add
<Market, Language>to class instantiations - Update configurations: Move environment configs to your project
- Create typed hooks: Use
createSiteaccessHook()for React integration
Next.js Integration
Automatic Routing Configuration
Generate Next.js internationalization routing from your environment config:
import { generateNextIntlRouting } from '@netgen/storyblok-siteaccess';
import { defineRouting } from 'next-intl/routing';
// Generate routing configuration
const routingConfig = generateNextIntlRouting(environmentConfig, {
defaultLocale: 'en',
alternateLinks: false,
localeCookie: false,
localePrefix: { mode: 'always' }
});
export const routing = defineRouting(routingConfig);Storyblok Visual Editor Redirects
Generate redirects for Storyblok's visual editor:
import { generateStoryblokRedirects } from '@netgen/storyblok-siteaccess';
// Generate redirects
export const storyblokRedirects = generateStoryblokRedirects(environmentConfig, {
permanent: false
});
// Use in next.config.js
module.exports = {
async redirects() {
return storyblokRedirects;
}
};Utility Functions
import {
getLocales,
getHosts,
getDomainConfig,
isValidLocale,
getDefaultLocaleForHost
} from '@netgen/storyblok-siteaccess';
// Get all locales
const locales = getLocales(environmentConfig);
// Check if locale is valid
const isValid = isValidLocale(environmentConfig, 'en-US');
// Get domain configuration
const domainConfig = getDomainConfig(environmentConfig, 'example.com');Integration with next-intl
import { isValidLocale } from '@netgen/storyblok-siteaccess';
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ requestLocale }) => {
const locale = await requestLocale;
// Validate locale using the package utility
if (!isValidLocale(environmentConfig, locale)) {
// Handle invalid locale
return { locale: 'en', messages: {} };
}
return {
locale,
messages: (await import(`./messages/${locale}.json`)).default
};
});API Reference
Utility Functions
generateNextIntlRouting(config, options?): Generate Next.js internationalization routinggenerateStoryblokRedirects(config, options?): Generate Storyblok visual editor redirectsgetLocales(config): Extract all unique localesgetHosts(config): Extract all unique hostsgetDomainConfig(config, host): Get domain configuration for specific hostisValidLocale(config, locale): Check if locale exists in configurationgetDefaultLocaleForHost(config, host): Get default locale for specific host
Types
NextRoutingConfig: Next.js routing configuration interfaceNextRedirectConfig: Next.js redirect configuration interfaceNextDomainConfig: Next.js domain configuration interface
License
ISC
