A TypeScript-based framework for building customizable, embeddable User Generated Content (UGC) widgets with multiple display layouts. Deploy as serverless AWS Lambda functions to showcase social media content across your digital properties.
Stackla Widget Templates provides a robust development environment for creating interactive, accessible UGC widgets. Built with modern web technologies and designed for scalability, this framework enables you to:
- Build Custom Widgets: Create unique UGC displays using pre-built templates or start from scratch
- Multiple Layouts: Choose from carousel, grid, masonry, waterfall, and more
- Serverless Architecture: Deploy as AWS Lambda functions for optimal performance
- Accessibility First: WCAG 2.1 AA compliant with comprehensive accessibility features
- TypeScript-Powered: Fully typed for better developer experience and code quality
- Architecture
- Prerequisites
- Quick Start
- Development Workflow
- Available Widgets
- Project Structure
- Configuration
- Testing
- Deployment
- Accessibility
- Contributing
- Resources
- Language: TypeScript 5.5+, JavaScript, JSX/TSX
- Runtime: Node.js 20.x (see
.nvmrc) - Build System: ESBuild with custom configuration
- Styling: SCSS with PostCSS processing
- Templates: Handlebars
- Framework: AWS Serverless Framework
- Testing: Playwright (E2E), Vitest (unit tests)
- Package Management: npm workspaces
βββββββββββββββββββββββββββββββββββββββββββββββ
β Widget Templates Repo β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β Widgets (carousel, grid, masonry, etc.) β
β β β
β Build System (ESBuild + SCSS) β
β β β
β Lambda Function Handler β
β β β
β AWS Lambda Deployment β
βββββββββββββββββββββββββββββββββββββββββββββββ
Each widget follows a consistent structure:
widgets/[widget-name]/
βββ widget.tsx # Main widget component (React-like JSX)
βββ widget.scss # Widget-specific styles
βββ layout.hbs # Optional Handlebars layout template
βββ tile.hbs # Optional tile template
βββ config.ts # Widget configuration
βββ [name].lib.ts # Widget-specific logic
βββ _*.scss # Partial SCSS files
- Node.js: Version 20.x (use
nvmto switch:nvm use) - npm: Version 8.x or higher
- Git: For cloning and submodule management
- Code Editor: VS Code recommended for optimal TypeScript support
git clone https://github.com/Stackla/stackla-widget-templates.git
cd stackla-widget-templatesFor forked repositories:
git clone https://your-github-repo-here
cd stackla-widget-templatesThe setup script handles all initialization:
./setup.shThis script will:
- Initialize and update git submodules (widget-utils)
- Install all npm dependencies
- Install Playwright with Chromium
- Configure remote repositories
Alternative Manual Setup (if setup.sh fails):
# Initialize submodules
git submodule init
git submodule update --remote --recursive
# Install dependencies
npm install
# Install Playwright (optional, for E2E testing)
npx playwright install --with-deps chromiumCritical: Always build widget-utils before the main project:
# Build widget-utils submodule (REQUIRED first step)
npm run build:utils
# Build main project
npm run buildnpm run startThe development server will start at http://localhost:4003
Open your browser and navigate to:
http://localhost:4003/preview?widgetType=carousel
Replace carousel with any available widget type (grid, masonry, waterfall, etc.)
π Congratulations! You're ready to start building widgets.
# Development build with source maps and hot reload
npm run start # Starts dev server (localhost:4003)
# Watch mode (auto-rebuild on file changes)
npm run watch
# Production build
npm run build # or npm run build:production
# Build for specific environments
npm run build:development # Development environment
npm run build:staging # Staging environment
npm run build:pipeline # CI/CD pipeline
# Build widget-utils submodule
npm run build:utils # Production build
npm run build:utils:dev # Development build| Environment | Port | Command |
|---|---|---|
| Development | 4003 | npm run start |
| Testing | 4003 | npm run start:test |
| Pipeline | 4003 | npm run start:lambda:pipeline |
# Linting
npm run lint # Run ESLint + Stylelint
npm run lint:fix # Auto-fix linting issues
npm run eslint # Run ESLint only
npm run stylelint # Run Stylelint only
# Type Checking
npm run typecheck # TypeScript validation
# Formatting
npm run prettier # Format code with Prettier# Unit Tests (Vitest)
npm test # Run all unit tests
# E2E Tests (Playwright)
npm run test:e2e # Run all E2E tests
npm run test:e2e:debug # Debug mode
npm run test:e2e:pipeline # Run in CI/CD pipeline (sharded)
npm run test:playwright:debug # Open Playwright UI
# Test Build
npm run test:build # Build for testing environment
npm run start:test # Start test server with watch modeThe repository includes multiple pre-built widget templates:
| Widget | Description | Key Features |
|---|---|---|
| Carousel | Horizontal scrolling carousel | Swiper integration, inline tiles, auto-scroll |
| Grid | Traditional grid layout | Responsive columns, masonry option |
| Masonry | Pinterest-style layout | Dynamic column layout, waterfall effect |
| Waterfall | Vertical scrolling infinite feed | Lazy loading, infinite scroll |
| Quadrant | Four-quadrant display | Sectioned content areas |
| Storyline | Linear story progression | Sequential content display |
| Storypage | Full-page stories | Immersive story experience |
| Shortvideo | Video-focused widget | Video playback, mobile-optimized |
| Nightfall | Dark-themed widget | Night mode styling |
| Blankcanvas | Starter template | Minimal starting point for custom widgets |
| Starter Project | Learning template | Educational examples with guided activities |
- Copy the
widgets/starter-projectorwidgets/blankcanvasdirectory - Rename to your widget name (e.g.,
widgets/my-widget) - Customize the widget files:
widget.tsx- Main component logicwidget.scss- Stylingconfig.ts- Widget configuration- Templates (
.hbsfiles) - Layout and tile structure
- Build and test your widget:
npm run build npm run start # Visit http://localhost:4003/preview?widgetType=my-widget
stackla-widget-templates/
βββ .github/ # GitHub workflows and templates
β βββ workflows/ # CI/CD pipelines
β β βββ main.yml # Main CI pipeline
β β βββ release.yml # Deployment workflow
β β βββ e2e.yml # E2E testing workflow
β βββ ISSUE_TEMPLATE/ # Issue templates
βββ config/ # Environment configurations
βββ dist/ # Build output (gitignored)
βββ guides/ # Tutorial guides
β βββ creating-auto-scrolling-carousel-using-blank-canvas/
β βββ creating-gallery-widget-by-using-the-blank-canvas-widget/
βββ packages/ # npm workspaces
β βββ widget-utils/ # Core utilities (git submodule)
βββ src/ # Core application logic
β βββ functions/ # AWS Lambda handlers
β β βββ main/ # Main Lambda function
β βββ libs/ # Shared libraries
β βββ tests/ # Test utilities
βββ tests/ # Test fixtures and E2E tests
β βββ e2e/ # Playwright E2E tests
β β βββ assertions/ # Reusable test assertions
β β βββ locators/ # Component locators
β β βββ utilities/ # Test utilities
β βββ fixtures/ # Test data
βββ types/ # TypeScript type definitions
βββ views/ # Server-side view templates
βββ widgets/ # Widget implementations
β βββ carousel/
β βββ grid/
β βββ masonry/
β βββ starter-project/ # Learning template
β βββ [other widgets]/
βββ .eslintrc # ESLint configuration
βββ .nvmrc # Node version (20)
βββ .prettierrc # Prettier configuration
βββ .stylelintrc.json # Stylelint configuration
βββ ACCESSIBILITY_IMPLEMENTATION_GUIDE.md # Accessibility guide
βββ ACCESSIBILITY_QUICK_REFERENCE.md # Quick accessibility reference
βββ esbuild.js # Custom build configuration
βββ package.json # Project dependencies and scripts
βββ playwright.config.ts # Playwright configuration
βββ serverless.ts # AWS Serverless configuration
βββ setup.sh # Setup automation script
βββ tsconfig.json # TypeScript configuration
βββ vitest.config.ts # Vitest test configuration
The build system uses APP_ENV to configure behavior:
export APP_ENV=production # Production builds
export APP_ENV=staging # Staging environment
export APP_ENV=development # Development builds
export APP_ENV=testing # Testing environment
export APP_ENV=pipeline # CI/CD pipeline| Environment | URL |
|---|---|
| Production | https://templates.stackla.com |
| Staging | https://templates.teaser.stackla.com |
| Development | http://localhost:4003 |
| Testing | http://localhost:4003 |
Custom JSX configuration in tsconfig.json:
{
"jsx": "react",
"jsxFactory": "createElement",
"jsxFragmentFactory": "createFragment"
}This enables React-like JSX syntax without React dependency.
Custom build process defined in esbuild.js:
- TypeScript compilation
- SCSS processing with PostCSS
- Asset handling and copying
- Source map generation
- SVG sprite generation
- Hot reload support
Playwright E2E Tests (tests/e2e/):
- assertions/: Reusable assertions shared across tests
- locators/: Component locators encapsulated in closures for reusability
- utilities/: General utility functions for test setup
# Run all E2E tests
npm run test:e2e
# Debug mode (step through tests)
npm run test:e2e:debug
# Open Playwright UI for interactive debugging
npm run test:playwright:debug
# Run unit tests
npm test
# CI/CD pipeline testing (sharded across 3 containers)
npm run test:e2e:pipelineExample test structure:
import { test, expect } from '@playwright/test';
import { widgetLocators } from './locators/widget.locators';
import { assertWidgetLoaded } from './assertions/widget.assertions';
test('widget displays correctly', async ({ page }) => {
await page.goto('http://localhost:4003/preview?widgetType=carousel');
await assertWidgetLoaded(page);
const tiles = widgetLocators(page).tiles;
await expect(tiles.first()).toBeVisible();
});The project uses Serverless Framework for deployment:
# Deploy to staging
sls deploy --stage staging
# Deploy to production
sls deploy --stage productionGitHub Actions Workflows:
-
main.yml - Continuous Integration
- Triggers: PRs and pushes to master
- Steps: Build β Lint β Type Check β Test β E2E Tests
-
release.yml - Deployment
- Trigger: Manual workflow dispatch
- Environments: staging, production
- Steps: E2E Tests β Build β Deploy to AWS β Sync Assets to S3
Defined in serverless.ts:
- Lambda function configuration
- API Gateway setup
- Deployment bucket settings
- Environment-specific variables
For manual deployments:
# Build for target environment
npm run build:staging
# Deploy via Serverless Framework
sls deploy --stage staging --region us-west-1
# View deployment info
sls info --stage stagingThis project is committed to WCAG 2.1 AA compliance. Comprehensive accessibility documentation is available:
- ACCESSIBILITY_IMPLEMENTATION_GUIDE.md: Complete implementation guide
- ACCESSIBILITY_QUICK_REFERENCE.md: Quick checklist for developers
- β
Semantic HTML structure (
<main>,<section>,<article>,<nav>) - β ARIA attributes for screen readers
- β Keyboard navigation support (Tab, Arrow keys, Enter, Space)
- β Focus management with visible indicators
- β High contrast mode support
- β Skip links for efficient navigation
- β Proper heading hierarchy
- β Alternative text for images
- β Color contrast compliance
When creating or modifying widgets:
- Use semantic HTML elements
- Add appropriate ARIA labels and roles
- Implement keyboard navigation
- Ensure visible focus indicators (3px outline minimum)
- Test with screen readers
- Verify color contrast ratios (4.5:1 for text)
- Add skip links for long content
- Support high contrast mode
- Follow existing patterns: Review similar widgets before starting
- Minimal changes: Make surgical, precise modifications
- Code quality: Run lint and typecheck before committing
- Test coverage: Ensure changes don't break existing functionality
- Documentation: Update docs for significant changes
# Validate your changes
npm run build:utils # Build dependencies
npm run build # Build project
npm run lint # Check code style
npm run typecheck # Validate TypeScript
npm test # Run unit tests
npm run test:e2e # Run E2E tests- Create feature branch from
master - Make changes following coding standards
- Run validation suite
- Submit pull request with clear description
- Address CI/CD feedback
- Merge after approval
- TypeScript: Strict mode enabled, follow ESLint rules
- SCSS: Follow Stylelint configuration
- Formatting: Use Prettier for consistent formatting
- Comments: Add only when necessary for complex logic
- Naming: Use descriptive, consistent naming conventions
- Nosto UGC Documentation: https://docs.nosto.com/ugc
- Widget Development Guide: https://docs.nosto.com/ugc/widgets-nextgen/getting-started/creating-your-first-widget
- Blank Canvas Tutorial: https://docs.nosto.com/ugc/widgets-nextgen/getting-started/creating-your-first-widget/creating-a-widget-from-blank-canvas
- Starter Project Activity:
widgets/starter-project/README.md- Guided learning activity - Tutorial Guides:
guides/directory contains step-by-step tutorials:- Creating auto-scrolling carousel
- Building gallery widgets
- Serverless Framework Docs
- Playwright Documentation
- TypeScript Documentation
- ESBuild Documentation
- WCAG 2.1 Guidelines
"Could not resolve @stackla/widget-utils" errors
# Solution: Build widget-utils submodule first
npm run build:utilsPlaywright installation failures
# Use ignore-scripts to bypass Cypress in restricted networks
npm install --ignore-scriptsSubmodule not initialized
# Reinitialize submodules
git submodule init
git submodule update --remote --recursivePort already in use
# Kill process using port 4003
lsof -ti:4003 | xargs kill -9
# Or use different environment (port 4003)
npm run start:testBuild failures after pulling latest changes
# Clean and rebuild
rm -rf node_modules dist
npm install
npm run build:utils
npm run buildDeveloped and maintained by the Stackla (Nosto) team and community contributors.
Ready to build amazing widgets? Start with the Quick Start guide or explore the starter project for a guided learning experience!