@thierrynakoa/fire-flow 12.2.1 → 13.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CREDITS.md +25 -0
- package/DOMINION-FLOW-OVERVIEW.md +182 -38
- package/README.md +399 -455
- package/TROUBLESHOOTING.md +264 -264
- package/agents/fire-debugger.md +54 -0
- package/agents/fire-executor.md +1610 -1033
- package/agents/fire-fact-checker.md +1 -1
- package/agents/fire-planner.md +85 -17
- package/agents/fire-project-researcher.md +1 -1
- package/agents/fire-researcher.md +4 -22
- package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
- package/agents/fire-reviewer.md +552 -499
- package/agents/fire-verifier.md +114 -19
- package/bin/cli.js +18 -101
- package/commands/fire-0-orient.md +2 -2
- package/commands/fire-1a-new.md +50 -15
- package/commands/fire-1c-setup.md +33 -5
- package/commands/fire-1d-discuss.md +87 -1
- package/commands/fire-2-plan.md +556 -527
- package/commands/fire-3-execute.md +2046 -1356
- package/commands/fire-4-verify.md +975 -906
- package/commands/fire-5-handoff.md +46 -5
- package/commands/fire-6-resume.md +2 -31
- package/commands/fire-add-new-skill.md +138 -19
- package/commands/fire-autonomous.md +14 -2
- package/commands/fire-complete-milestone.md +1 -1
- package/commands/fire-cost.md +179 -183
- package/commands/fire-debug.md +1 -6
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +2 -15
- package/commands/fire-map-codebase.md +1 -1
- package/commands/fire-migrate-database.md +548 -0
- package/commands/fire-new-milestone.md +1 -1
- package/commands/fire-reflect.md +1 -2
- package/commands/fire-research.md +142 -21
- package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
- package/commands/fire-scaffold.md +297 -0
- package/commands/fire-search.md +1 -2
- package/commands/fire-security-scan.md +483 -484
- package/commands/fire-setup.md +359 -0
- package/commands/fire-skill.md +770 -0
- package/commands/fire-skills-diff.md +506 -506
- package/commands/fire-skills-history.md +388 -388
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +470 -470
- package/commands/fire-test.md +5 -5
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/commands/fire-validate-skills.md +282 -0
- package/commands/fire-vuln-scan.md +492 -493
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -24
- package/plugin.json +7 -7
- package/references/autonomy-levels.md +235 -0
- package/references/behavioral-directives.md +95 -3
- package/references/blocker-tracking.md +1 -1
- package/references/circuit-breaker.md +93 -2
- package/references/context-engineering.md +227 -9
- package/references/honesty-protocols.md +70 -1
- package/references/issue-to-pr-pipeline.md +149 -150
- package/references/metrics-and-trends.md +1 -2
- package/references/research-improvements.md +4 -108
- package/references/sdlc-mapping.md +73 -0
- package/references/state-machine.md +151 -0
- package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
- package/skills-library/SKILLS-INDEX.md +57 -558
- package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
- package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
- package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
- package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
- package/skills-library/_general/automation/settings-gui-generator.md +172 -0
- package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
- package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
- package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
- package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
- package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
- package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
- package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
- package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
- package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
- package/skills-library/_general/frontend/color-token-migration.md +112 -0
- package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
- package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
- package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
- package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
- package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
- package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
- package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
- package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
- package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
- package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
- package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
- package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
- package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
- package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
- package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
- package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
- package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
- package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
- package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
- package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
- package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
- package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
- package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
- package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
- package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
- package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
- package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
- package/skills-library/_general/methodology/dead-code-activation.md +123 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
- package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
- package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
- package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
- package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
- package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
- package/skills-library/_general/performance/liveclock-extraction.md +112 -0
- package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
- package/skills-library/_general/performance/use-visible-interval.md +131 -0
- package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
- package/skills-library/_quarantine/README.md +30 -0
- package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
- package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
- package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
- package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
- package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
- package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
- package/skills-library/api-patterns/graphql-content-queries.md +708 -0
- package/skills-library/appointment-scheduler-design.md +423 -0
- package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
- package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
- package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
- package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
- package/skills-library/automation/scheduled-content-publishing.md +608 -0
- package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
- package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
- package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
- package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
- package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
- package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
- package/skills-library/cms-patterns/content-branch-preview.md +515 -0
- package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
- package/skills-library/cms-patterns/mdx-component-content.md +649 -0
- package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
- package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
- package/skills-library/complexity-metrics/complexity-divider.md +707 -0
- package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
- package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
- package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
- package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
- package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
- package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
- package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
- package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
- package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
- package/skills-library/creative-multimedia/og-image-generator.md +635 -0
- package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
- package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
- package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
- package/skills-library/creative-multimedia/svg-generation.md +750 -0
- package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
- package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
- package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
- package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
- package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
- package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
- package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
- package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
- package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
- package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
- package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
- package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
- package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
- package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
- package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
- package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
- package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
- package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
- package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
- package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
- package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
- package/skills-library/database-solutions/content-publishing-states.md +631 -0
- package/skills-library/database-solutions/database-schema-designer.md +522 -0
- package/skills-library/database-solutions/er-diagram-components.md +569 -0
- package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
- package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
- package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
- package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
- package/skills-library/database-solutions/normalization-validator.md +778 -0
- package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
- package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
- package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
- package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
- package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
- package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
- package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
- package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
- package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
- package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
- package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
- package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
- package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
- package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
- package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
- package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
- package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
- package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
- package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
- package/skills-library/deployment-security/SECURITY.md +41 -0
- package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
- package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
- package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
- package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
- package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
- package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
- package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
- package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
- package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
- package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
- package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
- package/skills-library/deployment-security/vps-deployment.md +135 -0
- package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
- package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
- package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
- package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
- package/skills-library/document-processing/md-to-word-converter.md +318 -0
- package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
- package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
- package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
- package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
- package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
- package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
- package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
- package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
- package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
- package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
- package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
- package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
- package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
- package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
- package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
- package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
- package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
- package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
- package/skills-library/ecommerce/inventory-stock-management.md +270 -0
- package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
- package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
- package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
- package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
- package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
- package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
- package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
- package/skills-library/excalidraw-diagrams/LICENSE +21 -0
- package/skills-library/excalidraw-diagrams/README.md +178 -0
- package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
- package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
- package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
- package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
- package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
- package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
- package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
- package/skills-library/infrastructure/observability-designer.md +264 -0
- package/skills-library/infrastructure/performance-profiler.md +621 -0
- package/skills-library/installer-wizard-patterns.md +249 -0
- package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
- package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
- package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
- package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
- package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
- package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
- package/skills-library/integrations/headless-cms-architecture.md +484 -0
- package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
- package/skills-library/integrations/payload-cms-patterns.md +674 -0
- package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
- package/skills-library/integrations/rss-podcast-integration.md +300 -0
- package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/marketing/campaign-analytics.md +97 -0
- package/skills-library/marketing/content-creator.md +105 -0
- package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
- package/skills-library/marketing/social-media-analyzer.md +81 -0
- package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
- package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
- package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
- package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
- package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
- package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
- package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
- package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
- package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
- package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
- package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
- package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
- package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
- package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
- package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
- package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
- package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
- package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
- package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
- package/skills-library/methodology/tech-debt-tracker.md +570 -0
- package/skills-library/parallel-debug/SKILL.md +60 -0
- package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
- package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
- package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
- package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
- package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
- package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
- package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
- package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
- package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
- package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
- package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
- package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
- package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
- package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
- package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
- package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
- package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
- package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
- package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
- package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
- package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
- package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
- package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
- package/skills-library/security/admin-deletion-safety.md +396 -0
- package/skills-library/security/application-vuln-patterns.md +477 -0
- package/skills-library/security/env-secrets-manager.md +686 -0
- package/skills-library/security/secure-ai-application-templates.md +347 -0
- package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
- package/skills-library/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
- package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
- package/skills-library/system-context/SKILL.md +40 -0
- package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
- package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
- package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
- package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
- package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
- package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
- package/skills-library/testing/playwright-api-security-tests.md +202 -0
- package/skills-library/toolbox/SKILL.md +84 -0
- package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
- package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
- package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
- package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
- package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
- package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills-library/wordpress-style-theme-components.md +1526 -0
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/DECISION_LOG.md +0 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +6 -6
- package/templates/skill-api-integration.md +106 -0
- package/templates/skill-architecture-pattern.md +92 -0
- package/templates/skill-debug-pattern.md +98 -0
- package/templates/skill-devops-recipe.md +107 -0
- package/templates/skill-general.md +65 -0
- package/templates/skill-ui-component.md +113 -0
- package/tools/uat-runner.py +179 -0
- package/version.json +7 -3
- package/workflows/handoff-session.md +2 -2
- package/workflows/new-project.md +2 -2
- package/workflows/plan-phase.md +1 -1
- package/.claude-plugin/plugin.json +0 -64
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
- package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
- package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
- package/skills-library/specialists/api-architecture/api-designer.md +0 -49
- package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
- package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
- package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
- package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
- package/skills-library/specialists/backend/django-expert.md +0 -52
- package/skills-library/specialists/backend/fastapi-expert.md +0 -52
- package/skills-library/specialists/backend/laravel-specialist.md +0 -52
- package/skills-library/specialists/backend/nestjs-expert.md +0 -51
- package/skills-library/specialists/backend/rails-expert.md +0 -53
- package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
- package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
- package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
- package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
- package/skills-library/specialists/data-ml/rag-architect.md +0 -51
- package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
- package/skills-library/specialists/frontend/angular-architect.md +0 -52
- package/skills-library/specialists/frontend/flutter-expert.md +0 -51
- package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
- package/skills-library/specialists/frontend/react-native-expert.md +0 -50
- package/skills-library/specialists/frontend/vue-expert.md +0 -51
- package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
- package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
- package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
- package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
- package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
- package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
- package/skills-library/specialists/languages/cpp-pro.md +0 -74
- package/skills-library/specialists/languages/csharp-developer.md +0 -69
- package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
- package/skills-library/specialists/languages/golang-pro.md +0 -51
- package/skills-library/specialists/languages/java-architect.md +0 -49
- package/skills-library/specialists/languages/javascript-pro.md +0 -68
- package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
- package/skills-library/specialists/languages/php-pro.md +0 -49
- package/skills-library/specialists/languages/python-pro.md +0 -52
- package/skills-library/specialists/languages/react-expert.md +0 -51
- package/skills-library/specialists/languages/rust-engineer.md +0 -50
- package/skills-library/specialists/languages/sql-pro.md +0 -56
- package/skills-library/specialists/languages/swift-expert.md +0 -69
- package/skills-library/specialists/languages/typescript-pro.md +0 -51
- package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
- package/skills-library/specialists/platform/embedded-systems.md +0 -53
- package/skills-library/specialists/platform/game-developer.md +0 -53
- package/skills-library/specialists/platform/salesforce-developer.md +0 -53
- package/skills-library/specialists/platform/shopify-expert.md +0 -49
- package/skills-library/specialists/platform/wordpress-pro.md +0 -49
- package/skills-library/specialists/quality/code-documenter.md +0 -51
- package/skills-library/specialists/quality/code-reviewer.md +0 -67
- package/skills-library/specialists/quality/debugging-wizard.md +0 -51
- package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
- package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
- package/skills-library/specialists/quality/playwright-expert.md +0 -65
- package/skills-library/specialists/quality/spec-miner.md +0 -56
- package/skills-library/specialists/quality/test-master.md +0 -65
- package/skills-library/specialists/security/secure-code-guardian.md +0 -55
- package/skills-library/specialists/security/security-reviewer.md +0 -53
- package/skills-library/specialists/workflow/architecture-designer.md +0 -53
- package/skills-library/specialists/workflow/cli-developer.md +0 -70
- package/skills-library/specialists/workflow/feature-forge.md +0 -65
- package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
- package/skills-library/specialists/workflow/the-fool.md +0 -62
- /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
# Open Graph Image Generator
|
|
2
|
+
## Description
|
|
3
|
+
|
|
4
|
+
Generate dynamic Open Graph (OG) images programmatically for social media previews. Covers two production approaches: Satori + @vercel/og for edge deployment, and Sharp + Canvas for any Node.js server. Includes social card templates, caching strategies, meta tags, and testing workflows.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
- Building a blog, course platform, or content site that needs unique social preview images per page
|
|
9
|
+
- Generating branded cards with dynamic text (title, author, date) for link sharing
|
|
10
|
+
- Creating consistent OG images across hundreds or thousands of pages without manual design
|
|
11
|
+
- Need to control how your links appear on Twitter/X, Facebook, LinkedIn, Discord, Slack
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Approach A: Satori + @vercel/og (Edge / Vercel)
|
|
16
|
+
|
|
17
|
+
### How It Works
|
|
18
|
+
|
|
19
|
+
Satori converts JSX (HTML/CSS subset) to SVG entirely in JavaScript/WebAssembly. The `@vercel/og` package wraps Satori with PNG rendering via Resvg-WASM. The entire pipeline runs on the edge with no server, no headless browser, no native dependencies.
|
|
20
|
+
|
|
21
|
+
**Pipeline:** JSX template --> Satori (SVG) --> Resvg-WASM (PNG) --> Response
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @vercel/og
|
|
27
|
+
# Satori is included as a dependency
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Limitations
|
|
31
|
+
|
|
32
|
+
Satori supports a **subset** of CSS. Know these constraints before designing:
|
|
33
|
+
|
|
34
|
+
- Only `display: flex` (no `grid`, no `block`, no `inline`)
|
|
35
|
+
- No `position: absolute` or `position: fixed`
|
|
36
|
+
- No CSS animations or transitions
|
|
37
|
+
- No `box-shadow` (use border or SVG filters)
|
|
38
|
+
- No pseudo-elements (`::before`, `::after`)
|
|
39
|
+
- Fonts must be loaded explicitly (no system fonts on edge)
|
|
40
|
+
- Background images work via `backgroundImage: url(...)` but must be absolute URLs
|
|
41
|
+
|
|
42
|
+
### Custom Font Loading
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// Fetch font file at build time or on first request
|
|
46
|
+
async function loadFont() {
|
|
47
|
+
const fontData = await fetch(
|
|
48
|
+
'https://cdn.example.com/fonts/Inter-Bold.ttf'
|
|
49
|
+
).then(res => res.arrayBuffer());
|
|
50
|
+
|
|
51
|
+
return fontData;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Complete API Route (Next.js App Router)
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// app/api/og/route.jsx
|
|
59
|
+
import { ImageResponse } from '@vercel/og';
|
|
60
|
+
|
|
61
|
+
export const runtime = 'edge';
|
|
62
|
+
|
|
63
|
+
export async function GET(request) {
|
|
64
|
+
const { searchParams } = new URL(request.url);
|
|
65
|
+
const title = searchParams.get('title') || 'Default Title';
|
|
66
|
+
const author = searchParams.get('author') || '';
|
|
67
|
+
const date = searchParams.get('date') || '';
|
|
68
|
+
const category = searchParams.get('category') || '';
|
|
69
|
+
|
|
70
|
+
// Load custom font
|
|
71
|
+
const interBold = await fetch(
|
|
72
|
+
new URL('../../assets/fonts/Inter-Bold.ttf', import.meta.url)
|
|
73
|
+
).then(res => res.arrayBuffer());
|
|
74
|
+
|
|
75
|
+
const interRegular = await fetch(
|
|
76
|
+
new URL('../../assets/fonts/Inter-Regular.ttf', import.meta.url)
|
|
77
|
+
).then(res => res.arrayBuffer());
|
|
78
|
+
|
|
79
|
+
return new ImageResponse(
|
|
80
|
+
(
|
|
81
|
+
<div
|
|
82
|
+
style={{
|
|
83
|
+
width: '100%',
|
|
84
|
+
height: '100%',
|
|
85
|
+
display: 'flex',
|
|
86
|
+
flexDirection: 'column',
|
|
87
|
+
justifyContent: 'space-between',
|
|
88
|
+
padding: '60px',
|
|
89
|
+
background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%)',
|
|
90
|
+
color: 'white',
|
|
91
|
+
fontFamily: 'Inter',
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{/* Top: Category badge */}
|
|
95
|
+
{category && (
|
|
96
|
+
<div
|
|
97
|
+
style={{
|
|
98
|
+
display: 'flex',
|
|
99
|
+
alignItems: 'center',
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
<span
|
|
103
|
+
style={{
|
|
104
|
+
background: '#3b82f6',
|
|
105
|
+
color: 'white',
|
|
106
|
+
padding: '8px 20px',
|
|
107
|
+
borderRadius: '20px',
|
|
108
|
+
fontSize: '20px',
|
|
109
|
+
fontWeight: 700,
|
|
110
|
+
textTransform: 'uppercase',
|
|
111
|
+
letterSpacing: '1px',
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
{category}
|
|
115
|
+
</span>
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
|
|
119
|
+
{/* Middle: Title */}
|
|
120
|
+
<div
|
|
121
|
+
style={{
|
|
122
|
+
display: 'flex',
|
|
123
|
+
flexDirection: 'column',
|
|
124
|
+
gap: '16px',
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
<h1
|
|
128
|
+
style={{
|
|
129
|
+
fontSize: title.length > 60 ? '42px' : '56px',
|
|
130
|
+
fontWeight: 700,
|
|
131
|
+
lineHeight: 1.2,
|
|
132
|
+
margin: 0,
|
|
133
|
+
color: '#f8fafc',
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{title}
|
|
137
|
+
</h1>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
{/* Bottom: Author + Date + Logo */}
|
|
141
|
+
<div
|
|
142
|
+
style={{
|
|
143
|
+
display: 'flex',
|
|
144
|
+
justifyContent: 'space-between',
|
|
145
|
+
alignItems: 'center',
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
|
149
|
+
{author && (
|
|
150
|
+
<span style={{ fontSize: '24px', color: '#94a3b8' }}>
|
|
151
|
+
{author}
|
|
152
|
+
</span>
|
|
153
|
+
)}
|
|
154
|
+
{date && (
|
|
155
|
+
<span style={{ fontSize: '18px', color: '#64748b' }}>
|
|
156
|
+
{date}
|
|
157
|
+
</span>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
<span
|
|
161
|
+
style={{
|
|
162
|
+
fontSize: '28px',
|
|
163
|
+
fontWeight: 700,
|
|
164
|
+
color: '#3b82f6',
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
YourBrand
|
|
168
|
+
</span>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
),
|
|
172
|
+
{
|
|
173
|
+
width: 1200,
|
|
174
|
+
height: 630,
|
|
175
|
+
fonts: [
|
|
176
|
+
{ name: 'Inter', data: interBold, weight: 700, style: 'normal' },
|
|
177
|
+
{ name: 'Inter', data: interRegular, weight: 400, style: 'normal' },
|
|
178
|
+
],
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Usage:** `https://yoursite.com/api/og?title=My+Course&author=Thierry&category=React`
|
|
185
|
+
|
|
186
|
+
### Satori Standalone (without Vercel)
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
import satori from 'satori';
|
|
190
|
+
import { Resvg } from '@resvg/resvg-js';
|
|
191
|
+
import fs from 'fs';
|
|
192
|
+
|
|
193
|
+
const fontData = fs.readFileSync('./fonts/Inter-Bold.ttf');
|
|
194
|
+
|
|
195
|
+
const svg = await satori(
|
|
196
|
+
{
|
|
197
|
+
type: 'div',
|
|
198
|
+
props: {
|
|
199
|
+
style: { width: '100%', height: '100%', display: 'flex', background: '#1a1a2e', color: 'white', alignItems: 'center', justifyContent: 'center', fontSize: '48px' },
|
|
200
|
+
children: 'Hello OG Image',
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
width: 1200,
|
|
205
|
+
height: 630,
|
|
206
|
+
fonts: [{ name: 'Inter', data: fontData, weight: 700 }],
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const resvg = new Resvg(svg, { fitTo: { mode: 'width', value: 1200 } });
|
|
211
|
+
const pngData = resvg.render();
|
|
212
|
+
fs.writeFileSync('og.png', pngData.asPng());
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Approach B: Sharp + Canvas (Any Node.js Server)
|
|
218
|
+
|
|
219
|
+
Works on any hosting provider. No edge runtime required. Uses `@napi-rs/canvas` (faster, prebuilt) or `canvas` (node-canvas, requires native deps).
|
|
220
|
+
|
|
221
|
+
### Installation
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
npm install sharp @napi-rs/canvas
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Complete Express Route
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
import express from 'express';
|
|
231
|
+
import sharp from 'sharp';
|
|
232
|
+
import { createCanvas, GlobalFonts } from '@napi-rs/canvas';
|
|
233
|
+
import path from 'path';
|
|
234
|
+
|
|
235
|
+
const app = express();
|
|
236
|
+
|
|
237
|
+
// Register custom fonts
|
|
238
|
+
GlobalFonts.registerFromPath(
|
|
239
|
+
path.resolve('./fonts/Inter-Bold.ttf'),
|
|
240
|
+
'InterBold'
|
|
241
|
+
);
|
|
242
|
+
GlobalFonts.registerFromPath(
|
|
243
|
+
path.resolve('./fonts/Inter-Regular.ttf'),
|
|
244
|
+
'InterRegular'
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
function wrapText(ctx, text, maxWidth) {
|
|
248
|
+
const words = text.split(' ');
|
|
249
|
+
const lines = [];
|
|
250
|
+
let currentLine = '';
|
|
251
|
+
|
|
252
|
+
for (const word of words) {
|
|
253
|
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
|
254
|
+
const { width } = ctx.measureText(testLine);
|
|
255
|
+
if (width > maxWidth && currentLine) {
|
|
256
|
+
lines.push(currentLine);
|
|
257
|
+
currentLine = word;
|
|
258
|
+
} else {
|
|
259
|
+
currentLine = testLine;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (currentLine) lines.push(currentLine);
|
|
263
|
+
return lines;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function generateOgImage({ title, author, date, category }) {
|
|
267
|
+
const WIDTH = 1200;
|
|
268
|
+
const HEIGHT = 630;
|
|
269
|
+
const PADDING = 60;
|
|
270
|
+
|
|
271
|
+
const canvas = createCanvas(WIDTH, HEIGHT);
|
|
272
|
+
const ctx = canvas.getContext('2d');
|
|
273
|
+
|
|
274
|
+
// Background gradient (simulated with rectangles)
|
|
275
|
+
const gradient = ctx.createLinearGradient(0, 0, WIDTH, HEIGHT);
|
|
276
|
+
gradient.addColorStop(0, '#0f172a');
|
|
277
|
+
gradient.addColorStop(0.5, '#1e293b');
|
|
278
|
+
gradient.addColorStop(1, '#0f172a');
|
|
279
|
+
ctx.fillStyle = gradient;
|
|
280
|
+
ctx.fillRect(0, 0, WIDTH, HEIGHT);
|
|
281
|
+
|
|
282
|
+
// Decorative accent line
|
|
283
|
+
ctx.fillStyle = '#3b82f6';
|
|
284
|
+
ctx.fillRect(PADDING, PADDING, 80, 6);
|
|
285
|
+
|
|
286
|
+
// Category badge
|
|
287
|
+
if (category) {
|
|
288
|
+
ctx.font = '18px InterBold';
|
|
289
|
+
const badgeText = category.toUpperCase();
|
|
290
|
+
const badgeWidth = ctx.measureText(badgeText).width + 32;
|
|
291
|
+
ctx.fillStyle = '#3b82f6';
|
|
292
|
+
roundRect(ctx, PADDING, PADDING + 30, badgeWidth, 36, 18);
|
|
293
|
+
ctx.fill();
|
|
294
|
+
ctx.fillStyle = '#ffffff';
|
|
295
|
+
ctx.fillText(badgeText, PADDING + 16, PADDING + 54);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Title
|
|
299
|
+
const titleY = category ? PADDING + 100 : PADDING + 60;
|
|
300
|
+
ctx.fillStyle = '#f8fafc';
|
|
301
|
+
ctx.font = `${title.length > 60 ? 42 : 56}px InterBold`;
|
|
302
|
+
const titleLines = wrapText(ctx, title, WIDTH - PADDING * 2);
|
|
303
|
+
const lineHeight = title.length > 60 ? 52 : 68;
|
|
304
|
+
titleLines.forEach((line, i) => {
|
|
305
|
+
ctx.fillText(line, PADDING, titleY + (i + 1) * lineHeight);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// Author
|
|
309
|
+
if (author) {
|
|
310
|
+
ctx.fillStyle = '#94a3b8';
|
|
311
|
+
ctx.font = '24px InterRegular';
|
|
312
|
+
ctx.fillText(author, PADDING, HEIGHT - PADDING - 30);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Date
|
|
316
|
+
if (date) {
|
|
317
|
+
ctx.fillStyle = '#64748b';
|
|
318
|
+
ctx.font = '18px InterRegular';
|
|
319
|
+
ctx.fillText(date, PADDING, HEIGHT - PADDING);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Brand logo text (bottom right)
|
|
323
|
+
ctx.fillStyle = '#3b82f6';
|
|
324
|
+
ctx.font = '28px InterBold';
|
|
325
|
+
ctx.textAlign = 'right';
|
|
326
|
+
ctx.fillText('YourBrand', WIDTH - PADDING, HEIGHT - PADDING);
|
|
327
|
+
ctx.textAlign = 'left'; // Reset
|
|
328
|
+
|
|
329
|
+
// Convert canvas to PNG buffer, then optimize with Sharp
|
|
330
|
+
const rawPng = canvas.toBuffer('image/png');
|
|
331
|
+
const optimized = await sharp(rawPng)
|
|
332
|
+
.png({ quality: 90, compressionLevel: 6 })
|
|
333
|
+
.toBuffer();
|
|
334
|
+
|
|
335
|
+
return optimized;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function roundRect(ctx, x, y, w, h, r) {
|
|
339
|
+
ctx.beginPath();
|
|
340
|
+
ctx.moveTo(x + r, y);
|
|
341
|
+
ctx.lineTo(x + w - r, y);
|
|
342
|
+
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
343
|
+
ctx.lineTo(x + w, y + h - r);
|
|
344
|
+
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
345
|
+
ctx.lineTo(x + r, y + h);
|
|
346
|
+
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
347
|
+
ctx.lineTo(x, y + r);
|
|
348
|
+
ctx.quadraticCurveTo(x, y, x + r, y);
|
|
349
|
+
ctx.closePath();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
app.get('/api/og', async (req, res) => {
|
|
353
|
+
const { title, author, date, category } = req.query;
|
|
354
|
+
|
|
355
|
+
if (!title) {
|
|
356
|
+
return res.status(400).json({ error: 'title parameter is required' });
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
try {
|
|
360
|
+
const imageBuffer = await generateOgImage({
|
|
361
|
+
title,
|
|
362
|
+
author: author || '',
|
|
363
|
+
date: date || '',
|
|
364
|
+
category: category || '',
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
res.setHeader('Content-Type', 'image/png');
|
|
368
|
+
res.setHeader('Cache-Control', 'public, max-age=86400, s-maxage=604800');
|
|
369
|
+
res.send(imageBuffer);
|
|
370
|
+
} catch (err) {
|
|
371
|
+
console.error('OG generation failed:', err);
|
|
372
|
+
res.status(500).json({ error: 'Failed to generate image' });
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Social Card Dimensions
|
|
380
|
+
|
|
381
|
+
| Platform | Dimensions | Aspect Ratio | Card Type |
|
|
382
|
+
|----------|-----------|--------------|-----------|
|
|
383
|
+
| Twitter/X | 1200 x 628 | ~1.91:1 | `summary_large_image` |
|
|
384
|
+
| Facebook | 1200 x 630 | ~1.91:1 | Default link preview |
|
|
385
|
+
| LinkedIn | 1200 x 627 | ~1.91:1 | Article/link share |
|
|
386
|
+
| Discord | 1200 x 630 | ~1.91:1 | Embed preview |
|
|
387
|
+
| Slack | 1200 x 630 | ~1.91:1 | Unfurl preview |
|
|
388
|
+
| Instagram | 1080 x 1080 | 1:1 | Shared post (not OG) |
|
|
389
|
+
| WhatsApp | 1200 x 630 | ~1.91:1 | Link preview |
|
|
390
|
+
| Pinterest | 1000 x 1500 | 2:3 | Pin image |
|
|
391
|
+
|
|
392
|
+
**Safe zone:** Keep critical text and logos at least 60px from any edge. Some platforms crop slightly or add rounded corners.
|
|
393
|
+
|
|
394
|
+
**Universal recommendation:** Use 1200 x 630 for all OG images. It works across every major platform.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Dynamic Data Injection
|
|
399
|
+
|
|
400
|
+
Pattern for generating course/article-specific OG images:
|
|
401
|
+
|
|
402
|
+
```javascript
|
|
403
|
+
// In your page's metadata (Next.js App Router example)
|
|
404
|
+
export async function generateMetadata({ params }) {
|
|
405
|
+
const course = await getCourse(params.slug);
|
|
406
|
+
|
|
407
|
+
const ogUrl = new URL('/api/og', process.env.NEXT_PUBLIC_SITE_URL);
|
|
408
|
+
ogUrl.searchParams.set('title', course.title);
|
|
409
|
+
ogUrl.searchParams.set('author', course.instructor.name);
|
|
410
|
+
ogUrl.searchParams.set('date', new Date(course.publishedAt).toLocaleDateString());
|
|
411
|
+
ogUrl.searchParams.set('category', course.category);
|
|
412
|
+
|
|
413
|
+
return {
|
|
414
|
+
title: course.title,
|
|
415
|
+
description: course.excerpt,
|
|
416
|
+
openGraph: {
|
|
417
|
+
title: course.title,
|
|
418
|
+
description: course.excerpt,
|
|
419
|
+
images: [{ url: ogUrl.toString(), width: 1200, height: 630 }],
|
|
420
|
+
},
|
|
421
|
+
twitter: {
|
|
422
|
+
card: 'summary_large_image',
|
|
423
|
+
title: course.title,
|
|
424
|
+
description: course.excerpt,
|
|
425
|
+
images: [ogUrl.toString()],
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
For Express/non-Next.js apps, inject the URL into your HTML template:
|
|
432
|
+
|
|
433
|
+
```javascript
|
|
434
|
+
app.get('/courses/:slug', async (req, res) => {
|
|
435
|
+
const course = await getCourse(req.params.slug);
|
|
436
|
+
const ogImageUrl = `${process.env.SITE_URL}/api/og?title=${encodeURIComponent(course.title)}&author=${encodeURIComponent(course.instructor)}`;
|
|
437
|
+
|
|
438
|
+
res.render('course', { course, ogImageUrl });
|
|
439
|
+
});
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
```html
|
|
443
|
+
<!-- In your template (EJS, Handlebars, etc.) -->
|
|
444
|
+
<meta property="og:image" content="<%= ogImageUrl %>" />
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Caching Strategy
|
|
450
|
+
|
|
451
|
+
OG images are fetched by crawlers (Twitterbot, facebookexternalhit, etc.), not by every user. Caching is critical to avoid re-generating on every crawl.
|
|
452
|
+
|
|
453
|
+
### Option 1: HTTP Cache Headers (simplest)
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
res.setHeader('Cache-Control', 'public, max-age=86400, s-maxage=604800');
|
|
457
|
+
// max-age: browser caches for 1 day
|
|
458
|
+
// s-maxage: CDN caches for 7 days
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Option 2: Pre-generate and Store
|
|
462
|
+
|
|
463
|
+
```javascript
|
|
464
|
+
import fs from 'fs/promises';
|
|
465
|
+
import path from 'path';
|
|
466
|
+
import crypto from 'crypto';
|
|
467
|
+
|
|
468
|
+
async function getOrGenerateOgImage(params) {
|
|
469
|
+
// Create deterministic cache key from params
|
|
470
|
+
const cacheKey = crypto
|
|
471
|
+
.createHash('md5')
|
|
472
|
+
.update(JSON.stringify(params))
|
|
473
|
+
.digest('hex');
|
|
474
|
+
|
|
475
|
+
const cachePath = path.resolve(`./cache/og/${cacheKey}.png`);
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
// Return cached version if it exists
|
|
479
|
+
const cached = await fs.readFile(cachePath);
|
|
480
|
+
return cached;
|
|
481
|
+
} catch {
|
|
482
|
+
// Generate fresh
|
|
483
|
+
const buffer = await generateOgImage(params);
|
|
484
|
+
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
485
|
+
await fs.writeFile(cachePath, buffer);
|
|
486
|
+
return buffer;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Invalidation: delete cached file when content changes
|
|
491
|
+
async function invalidateOgCache(params) {
|
|
492
|
+
const cacheKey = crypto
|
|
493
|
+
.createHash('md5')
|
|
494
|
+
.update(JSON.stringify(params))
|
|
495
|
+
.digest('hex');
|
|
496
|
+
|
|
497
|
+
const cachePath = path.resolve(`./cache/og/${cacheKey}.png`);
|
|
498
|
+
await fs.unlink(cachePath).catch(() => {}); // Ignore if not found
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Option 3: CDN with Purge on Content Update
|
|
503
|
+
|
|
504
|
+
If using Cloudflare, Fastly, or similar:
|
|
505
|
+
|
|
506
|
+
```javascript
|
|
507
|
+
// After updating a course title:
|
|
508
|
+
await fetch(`https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache`, {
|
|
509
|
+
method: 'POST',
|
|
510
|
+
headers: { Authorization: `Bearer ${CF_TOKEN}`, 'Content-Type': 'application/json' },
|
|
511
|
+
body: JSON.stringify({
|
|
512
|
+
files: [`https://yoursite.com/api/og?title=${encodeURIComponent(oldTitle)}`],
|
|
513
|
+
}),
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## HTML Meta Tags (Complete Set)
|
|
520
|
+
|
|
521
|
+
Include these in your `<head>` for full social media coverage:
|
|
522
|
+
|
|
523
|
+
```html
|
|
524
|
+
<!-- Open Graph (Facebook, LinkedIn, Discord, Slack, WhatsApp) -->
|
|
525
|
+
<meta property="og:type" content="article" />
|
|
526
|
+
<meta property="og:title" content="Advanced React Patterns — Full Course" />
|
|
527
|
+
<meta property="og:description" content="Learn compound components, render props, and custom hooks with real-world examples." />
|
|
528
|
+
<meta property="og:image" content="https://yoursite.com/api/og?title=Advanced+React+Patterns" />
|
|
529
|
+
<meta property="og:image:width" content="1200" />
|
|
530
|
+
<meta property="og:image:height" content="630" />
|
|
531
|
+
<meta property="og:image:alt" content="Course card: Advanced React Patterns" />
|
|
532
|
+
<meta property="og:url" content="https://yoursite.com/courses/react-patterns" />
|
|
533
|
+
<meta property="og:site_name" content="YourBrand" />
|
|
534
|
+
<meta property="og:locale" content="en_US" />
|
|
535
|
+
|
|
536
|
+
<!-- Twitter/X Card -->
|
|
537
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
538
|
+
<meta name="twitter:site" content="@yourbrand" />
|
|
539
|
+
<meta name="twitter:creator" content="@instructor" />
|
|
540
|
+
<meta name="twitter:title" content="Advanced React Patterns — Full Course" />
|
|
541
|
+
<meta name="twitter:description" content="Learn compound components, render props, and custom hooks with real-world examples." />
|
|
542
|
+
<meta name="twitter:image" content="https://yoursite.com/api/og?title=Advanced+React+Patterns" />
|
|
543
|
+
<meta name="twitter:image:alt" content="Course card: Advanced React Patterns" />
|
|
544
|
+
|
|
545
|
+
<!-- Article-specific (optional, improves rich previews) -->
|
|
546
|
+
<meta property="article:author" content="https://yoursite.com/instructors/thierry" />
|
|
547
|
+
<meta property="article:published_time" content="2025-11-15T09:00:00Z" />
|
|
548
|
+
<meta property="article:section" content="React" />
|
|
549
|
+
<meta property="article:tag" content="React" />
|
|
550
|
+
<meta property="article:tag" content="Patterns" />
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Key rules:**
|
|
554
|
+
- `og:image` must be an **absolute URL** (not relative)
|
|
555
|
+
- Image must be accessible without authentication
|
|
556
|
+
- Minimum recommended size: 1200 x 630
|
|
557
|
+
- Maximum file size: 8MB (Facebook), 5MB (Twitter) — aim for under 500KB
|
|
558
|
+
- Use `og:image:alt` for accessibility
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Testing OG Images
|
|
563
|
+
|
|
564
|
+
### Online Validators
|
|
565
|
+
|
|
566
|
+
| Tool | URL | Tests |
|
|
567
|
+
|------|-----|-------|
|
|
568
|
+
| **opengraph.xyz** | https://opengraph.xyz | Preview across all platforms, shows raw tags |
|
|
569
|
+
| **Twitter Card Validator** | https://cards-dev.twitter.com/validator | Official Twitter/X preview |
|
|
570
|
+
| **Facebook Sharing Debugger** | https://developers.facebook.com/tools/debug/ | Facebook preview + cache purge |
|
|
571
|
+
| **LinkedIn Post Inspector** | https://www.linkedin.com/post-inspector/ | LinkedIn-specific rendering |
|
|
572
|
+
| **metatags.io** | https://metatags.io | Multi-platform preview with editor |
|
|
573
|
+
|
|
574
|
+
### Local Testing
|
|
575
|
+
|
|
576
|
+
```javascript
|
|
577
|
+
// Quick visual test: save to file and open
|
|
578
|
+
import open from 'open'; // npm install open
|
|
579
|
+
import fs from 'fs/promises';
|
|
580
|
+
|
|
581
|
+
const buffer = await generateOgImage({
|
|
582
|
+
title: 'Advanced React Patterns — Full Course',
|
|
583
|
+
author: 'Thierry N.',
|
|
584
|
+
date: 'March 2026',
|
|
585
|
+
category: 'React',
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
await fs.writeFile('/tmp/og-test.png', buffer);
|
|
589
|
+
await open('/tmp/og-test.png');
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### Automated Visual Regression
|
|
593
|
+
|
|
594
|
+
```javascript
|
|
595
|
+
// In your test suite (Vitest/Jest)
|
|
596
|
+
import { describe, it, expect } from 'vitest';
|
|
597
|
+
import sharp from 'sharp';
|
|
598
|
+
|
|
599
|
+
describe('OG Image Generation', () => {
|
|
600
|
+
it('generates correct dimensions', async () => {
|
|
601
|
+
const buffer = await generateOgImage({ title: 'Test Title' });
|
|
602
|
+
const meta = await sharp(buffer).metadata();
|
|
603
|
+
expect(meta.width).toBe(1200);
|
|
604
|
+
expect(meta.height).toBe(630);
|
|
605
|
+
expect(meta.format).toBe('png');
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
it('handles long titles without overflow', async () => {
|
|
609
|
+
const buffer = await generateOgImage({
|
|
610
|
+
title: 'This Is an Extremely Long Course Title That Should Still Render Correctly Without Overflowing the Image Boundaries',
|
|
611
|
+
});
|
|
612
|
+
const meta = await sharp(buffer).metadata();
|
|
613
|
+
expect(meta.width).toBe(1200);
|
|
614
|
+
// Visual check: save to snapshots dir for manual review
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it('file size stays under 500KB', async () => {
|
|
618
|
+
const buffer = await generateOgImage({ title: 'Size Check' });
|
|
619
|
+
expect(buffer.length).toBeLessThan(500 * 1024);
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Force Social Platform Re-scrape
|
|
625
|
+
|
|
626
|
+
Platforms cache OG data aggressively. After updating an image:
|
|
627
|
+
|
|
628
|
+
- **Facebook:** Use the Sharing Debugger "Scrape Again" button
|
|
629
|
+
- **Twitter:** The Card Validator re-fetches automatically
|
|
630
|
+
- **LinkedIn:** Use Post Inspector to force refresh
|
|
631
|
+
- **Slack:** Edit the message or re-paste the link
|
|
632
|
+
- **Discord:** Append `?v=2` to the URL (cache buster)
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|