Overview
Section titled “Overview”Released.so is a changelog and release notes platform that provides embeddable widgets to display product updates. This documentation covers the complete setup process for integrating Released.so embeds in Forge apps while handling Content Security Policy (CSP) requirements.
Prerequisites
Section titled “Prerequisites”- A Forge app with UI components
- A Released.so account with an embed widget configured
- Access to your Released.so embed script URL
Configuration Steps
Section titled “Configuration Steps”Manifest Configuration
Section titled “Manifest Configuration”The Released.so embed requires multiple types of external resources:
| Permission Type | Address Pattern | Purpose |
|---|---|---|
scripts |
*.released.so |
Main embed script and dynamically loaded modules |
styles |
*.released.so |
CSS files including fonts (Inter font family) |
fonts |
*.released.so |
Web font files |
images |
*.released.so |
Post images and other visual assets |
fetch.client |
*.released.so |
API calls for loading content |
Add the necessary external permissions to your manifest.yml file to allow Released.so resources:
permissions: external: fetch: client: - address: "*.released.so" scripts: - address: "*.released.so" styles: - address: "*.released.so" fonts: - address: "*.released.so" images: - address: "*.released.so"Frontend Implementation
Section titled “Frontend Implementation”React/TypeScript Example
Section titled “React/TypeScript Example”import React, { useEffect } from 'react';
interface ReleasedEmbedProps { embedId: string; className?: string;}
export const ReleasedEmbed: React.FC<ReleasedEmbedProps> = ({ embedId, className = ''}) => { useEffect(() => { // Create script element const script = document.createElement('script'); script.src = 'https://embed.released.so/1/embed.js'; script.async = true; script.setAttribute('data-embed-id', embedId);
// Add to document head document.head.appendChild(script);
// Cleanup function return () => { document.head.removeChild(script); }; }, [embedId]);
return ( <div className={`released-embed ${className}`} id={`released-embed-${embedId}`} > {/* Released.so content will be injected here */} </div> );};HTML Example
Section titled “HTML Example”<!DOCTYPE html><html><head> <script src="https://embed.released.so/1/embed.js" data-embed-id="YOUR_EMBED_ID" async> </script></head><body> <div id="released-embed"> <!-- Released.so content will be injected here --> </div></body></html>Troubleshooting
Section titled “Troubleshooting”Common CSP Violations
Section titled “Common CSP Violations”If you encounter Content Security Policy violations, verify these configurations:
Script Loading Issues
Section titled “Script Loading Issues”Error: Loading the script 'https://embed.released.so/...' violates CSP directiveSolution: Ensure scripts: - address: "*.released.so" is in external permissions.
Style Loading Issues
Section titled “Style Loading Issues”Error: Loading stylesheet 'https://embed.released.so/fonts/inter/inter.css' blocked by CSPSolution: Add styles: - address: "*.released.so" to external permissions.
Image Loading Issues
Section titled “Image Loading Issues”Error: Loading image from 'https://cdn.released.so/...' blocked by CSPSolution: Add images: - address: "*.released.so" to external permissions.
Debugging Steps
Section titled “Debugging Steps”Check Browser DevTools
Look for CSP violation errors in the console
Verify Manifest
Ensure all required external permissions are present
Test Deploy
Run
forge deployafter manifest changesClear Cache
Browser cache might retain old CSP policies
Best Practices
Section titled “Best Practices”Security Considerations
Section titled “Security Considerations”- Use Specific Domains: We use
*.released.soto allow subdomains but limit to Released.so only - Avoid Wildcards: Don’t use
*for all domains - be specific to Released.so
Performance Optimization
Section titled “Performance Optimization”- Lazy Loading: Load the embed script only when needed
- Async Loading: Always use
asyncattribute on script tags