[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F7XT3VSXPA9MPCB4D8HG9T":3,"skill-same:01M6F7XT3VSXPA9MPCB4D8HG9T":84},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":61,"commitSha":62,"skillDirectory":63,"forksCount":64,"repositoryHtmlUrl":65,"repositoryHomepageUrl":66,"ownerHtmlUrl":67,"ownerBlogUrl":6,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M6F7XT3VSXPA9MPCB4D8HG9T","canva-deploy-integration",null,"Deploy Canva Connect API integrations to Vercel, Fly.io, and Cloud Run.\nUse when deploying Canva-powered applications to production,\nconfiguring platform-specific secrets, or setting up deployment pipelines.\nTrigger with phrases like \"deploy canva\", \"canva Vercel\",\n\"canva production deploy\", \"canva Cloud Run\", \"canva Fly.io\".","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fcanva-deploy-integration\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"deploy","canva deploy integration","canva","integration","run","code","connect","api","secrets","fly","Bash","integrations","read","write","edit","up","deployment","platform","io","design","2026-11-10 10:12:30",false,"---\nname: canva-deploy-integration\ndescription: |\n  Deploy Canva Connect API integrations to Vercel, Fly.io, and Cloud Run.\n  Use when deploying Canva-powered applications to production,\n  configuring platform-specific secrets, or setting up deployment pipelines.\n  Trigger with phrases like \"deploy canva\", \"canva Vercel\",\n  \"canva production deploy\", \"canva Cloud Run\", \"canva Fly.io\".\nallowed-tools: Read, Write, Edit, Bash(vercel:*), Bash(fly:*), Bash(gcloud:*)\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\ntags: [saas, design, canva]\ncompatible-with: claude-code\n---\n\n# Canva Deploy Integration\n\n## Overview\n\nDeploy Canva Connect API integrations to popular platforms with secure OAuth credential management. The Canva API requires server-side token exchange — client secrets and refresh tokens must never reach the browser.\n\n## Prerequisites\n\n- Canva OAuth credentials (client ID + secret)\n- Platform CLI installed (vercel, fly, or gcloud)\n- HTTPS domain for OAuth redirect URIs\n- Application code ready for deployment\n\n## Vercel\n\n### Secrets\n\n```bash\n# Add Canva OAuth credentials\nvercel env add CANVA_CLIENT_ID production\nvercel env add CANVA_CLIENT_SECRET production\nvercel env add CANVA_REDIRECT_URI production  # e.g. https:\u002F\u002Fyour-app.vercel.app\u002Fauth\u002Fcanva\u002Fcallback\n```\n\n### vercel.json\n\n```json\n{\n  \"functions\": {\n    \"api\u002F**\u002F*.ts\": {\n      \"maxDuration\": 30\n    }\n  },\n  \"headers\": [\n    {\n      \"source\": \"\u002Fapi\u002F(.*)\",\n      \"headers\": [\n        { \"key\": \"Cache-Control\", \"value\": \"no-store\" }\n      ]\n    }\n  ]\n}\n```\n\n### API Route (Next.js \u002F Vercel Functions)\n\n```typescript\n\u002F\u002F api\u002Fcanva\u002Fcallback.ts — OAuth callback\nexport async function GET(req: Request) {\n  const url = new URL(req.url);\n  const code = url.searchParams.get('code');\n  const state = url.searchParams.get('state');\n\n  \u002F\u002F Exchange code for tokens (server-side only)\n  const tokens = await exchangeCodeForToken({\n    code: code!,\n    codeVerifier: await getVerifierFromSession(state!),\n    clientId: process.env.CANVA_CLIENT_ID!,\n    clientSecret: process.env.CANVA_CLIENT_SECRET!,\n    redirectUri: process.env.CANVA_REDIRECT_URI!,\n  });\n\n  \u002F\u002F Store tokens in your database\n  await saveTokens(userId, tokens);\n  return Response.redirect('\u002Fdashboard');\n}\n```\n\n## Fly.io\n\n### fly.toml\n\n```toml\napp = \"my-canva-app\"\nprimary_region = \"iad\"\n\n[env]\n  NODE_ENV = \"production\"\n  CANVA_REDIRECT_URI = \"https:\u002F\u002Fmy-canva-app.fly.dev\u002Fauth\u002Fcanva\u002Fcallback\"\n\n[http_service]\n  internal_port = 3000\n  force_https = true\n  auto_stop_machines = true\n  auto_start_machines = true\n```\n\n### Secrets\n\n```bash\nfly secrets set CANVA_CLIENT_ID=OCAxxxxxxxxxxxxxxxx\nfly secrets set CANVA_CLIENT_SECRET=xxxxxxxxxxxxxxxx\nfly deploy\n```\n\n## Google Cloud Run\n\n### Deploy Script\n\n```bash\n#!\u002Fbin\u002Fbash\nPROJECT_ID=\"${GOOGLE_CLOUD_PROJECT}\"\nSERVICE_NAME=\"canva-integration\"\nREGION=\"us-central1\"\n\n# Store secrets in Secret Manager\necho -n \"OCAxxxxxxxxxxxxxxxx\" | gcloud secrets create canva-client-id --data-file=-\necho -n \"xxxxxxxxxxxxxxxx\" | gcloud secrets create canva-client-secret --data-file=-\n\n# Build and deploy\ngcloud builds submit --tag gcr.io\u002F$PROJECT_ID\u002F$SERVICE_NAME\n\ngcloud run deploy $SERVICE_NAME \\\n  --image gcr.io\u002F$PROJECT_ID\u002F$SERVICE_NAME \\\n  --region $REGION \\\n  --platform managed \\\n  --allow-unauthenticated \\\n  --set-secrets=\"CANVA_CLIENT_ID=canva-client-id:latest,CANVA_CLIENT_SECRET=canva-client-secret:latest\" \\\n  --set-env-vars=\"CANVA_REDIRECT_URI=https:\u002F\u002F$SERVICE_NAME-xxxxx.run.app\u002Fauth\u002Fcanva\u002Fcallback\"\n```\n\n## Health Check\n\n```typescript\n\u002F\u002F api\u002Fhealth.ts — confirms Canva API connectivity\nexport async function GET() {\n  const start = Date.now();\n  let canvaStatus: string;\n\n  try {\n    const res = await fetch('https:\u002F\u002Fapi.canva.com\u002Frest\u002Fv1\u002Fusers\u002Fme', {\n      headers: { 'Authorization': `Bearer ${await getServiceToken()}` },\n      signal: AbortSignal.timeout(5000),\n    });\n    canvaStatus = res.ok ? 'healthy' : `error:${res.status}`;\n  } catch {\n    canvaStatus = 'unreachable';\n  }\n\n  return Response.json({\n    status: canvaStatus === 'healthy' ? 'healthy' : 'degraded',\n    services: { canva: { status: canvaStatus, latencyMs: Date.now() - start } },\n    timestamp: new Date().toISOString(),\n  });\n}\n```\n\n## Redirect URI Configuration\n\nAfter deploying, update your Canva integration settings with the production redirect URI:\n\n| Platform | Redirect URI Pattern |\n|----------|---------------------|\n| Vercel | `https:\u002F\u002Fyour-app.vercel.app\u002Fauth\u002Fcanva\u002Fcallback` |\n| Fly.io | `https:\u002F\u002Fyour-app.fly.dev\u002Fauth\u002Fcanva\u002Fcallback` |\n| Cloud Run | `https:\u002F\u002Fyour-service-xxxxx.run.app\u002Fauth\u002Fcanva\u002Fcallback` |\n| Custom Domain | `https:\u002F\u002Fapp.yourdomain.com\u002Fauth\u002Fcanva\u002Fcallback` |\n\n## Error Handling\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| OAuth callback fails | Redirect URI mismatch | Update URI in Canva dashboard |\n| Secret not found | Missing env var | Add via platform CLI |\n| Cold start timeout | OAuth exchange slow | Set min instances to 1 |\n| HTTPS required | HTTP redirect URI | All platforms default to HTTPS |\n\n## Resources\n\n- [Canva Creating Integrations](https:\u002F\u002Fwww.canva.dev\u002Fdocs\u002Fconnect\u002Fcreating-integrations\u002F)\n- [Vercel Docs](https:\u002F\u002Fvercel.com\u002Fdocs)\n- [Fly.io Docs](https:\u002F\u002Ffly.io\u002Fdocs)\n- [Cloud Run Docs](https:\u002F\u002Fcloud.google.com\u002Frun\u002Fdocs)\n\n## Next Steps\n\nFor webhook handling, see `canva-webhooks-events`.\n\n","# Canva Deploy Integration\n\n## Overview\n\nDeploy Canva Connect API integrations to popular platforms with secure OAuth credential management. The Canva API requires server-side token exchange — client secrets and refresh tokens must never reach the browser.\n\n## Prerequisites\n\n- Canva OAuth credentials (client ID + secret)\n- Platform CLI installed (vercel, fly, or gcloud)\n- HTTPS domain for OAuth redirect URIs\n- Application code ready for deployment\n\n## Vercel\n\n### Secrets\n\n```bash\n# Add Canva OAuth credentials\nvercel env add CANVA_CLIENT_ID production\nvercel env add CANVA_CLIENT_SECRET production\nvercel env add CANVA_REDIRECT_URI production  # e.g. https:\u002F\u002Fyour-app.vercel.app\u002Fauth\u002Fcanva\u002Fcallback\n```\n\n### vercel.json\n\n```json\n{\n  \"functions\": {\n    \"api\u002F**\u002F*.ts\": {\n      \"maxDuration\": 30\n    }\n  },\n  \"headers\": [\n    {\n      \"source\": \"\u002Fapi\u002F(.*)\",\n      \"headers\": [\n        { \"key\": \"Cache-Control\", \"value\": \"no-store\" }\n      ]\n    }\n  ]\n}\n```\n\n### API Route (Next.js \u002F Vercel Functions)\n\n```typescript\n\u002F\u002F api\u002Fcanva\u002Fcallback.ts — OAuth callback\nexport async function GET(req: Request) {\n  const url = new URL(req.url);\n  const code = url.searchParams.get('code');\n  const state = url.searchParams.get('state');\n\n  \u002F\u002F Exchange code for tokens (server-side only)\n  const tokens = await exchangeCodeForToken({\n    code: code!,\n    codeVerifier: await getVerifierFromSession(state!),\n    clientId: process.env.CANVA_CLIENT_ID!,\n    clientSecret: process.env.CANVA_CLIENT_SECRET!,\n    redirectUri: process.env.CANVA_REDIRECT_URI!,\n  });\n\n  \u002F\u002F Store tokens in your database\n  await saveTokens(userId, tokens);\n  return Response.redirect('\u002Fdashboard');\n}\n```\n\n## Fly.io\n\n### fly.toml\n\n```toml\napp = \"my-canva-app\"\nprimary_region = \"iad\"\n\n[env]\n  NODE_ENV = \"production\"\n  CANVA_REDIRECT_URI = \"https:\u002F\u002Fmy-canva-app.fly.dev\u002Fauth\u002Fcanva\u002Fcallback\"\n\n[http_service]\n  internal_port = 3000\n  force_https = true\n  auto_stop_machines = true\n  auto_start_machines = true\n```\n\n### Secrets\n\n```bash\nfly secrets set CANVA_CLIENT_ID=OCAxxxxxxxxxxxxxxxx\nfly secrets set CANVA_CLIENT_SECRET=xxxxxxxxxxxxxxxx\nfly deploy\n```\n\n## Google Cloud Run\n\n### Deploy Script\n\n```bash\n#!\u002Fbin\u002Fbash\nPROJECT_ID=\"${GOOGLE_CLOUD_PROJECT}\"\nSERVICE_NAME=\"canva-integration\"\nREGION=\"us-central1\"\n\n# Store secrets in Secret Manager\necho -n \"OCAxxxxxxxxxxxxxxxx\" | gcloud secrets create canva-client-id --data-file=-\necho -n \"xxxxxxxxxxxxxxxx\" | gcloud secrets create canva-client-secret --data-file=-\n\n# Build and deploy\ngcloud builds submit --tag gcr.io\u002F$PROJECT_ID\u002F$SERVICE_NAME\n\ngcloud run deploy $SERVICE_NAME \\\n  --image gcr.io\u002F$PROJECT_ID\u002F$SERVICE_NAME \\\n  --region $REGION \\\n  --platform managed \\\n  --allow-unauthenticated \\\n  --set-secrets=\"CANVA_CLIENT_ID=canva-client-id:latest,CANVA_CLIENT_SECRET=canva-client-secret:latest\" \\\n  --set-env-vars=\"CANVA_REDIRECT_URI=https:\u002F\u002F$SERVICE_NAME-xxxxx.run.app\u002Fauth\u002Fcanva\u002Fcallback\"\n```\n\n## Health Check\n\n```typescript\n\u002F\u002F api\u002Fhealth.ts — confirms Canva API connectivity\nexport async function GET() {\n  const start = Date.now();\n  let canvaStatus: string;\n\n  try {\n    const res = await fetch('https:\u002F\u002Fapi.canva.com\u002Frest\u002Fv1\u002Fusers\u002Fme', {\n      headers: { 'Authorization': `Bearer ${await getServiceToken()}` },\n      signal: AbortSignal.timeout(5000),\n    });\n    canvaStatus = res.ok ? 'healthy' : `error:${res.status}`;\n  } catch {\n    canvaStatus = 'unreachable';\n  }\n\n  return Response.json({\n    status: canvaStatus === 'healthy' ? 'healthy' : 'degraded',\n    services: { canva: { status: canvaStatus, latencyMs: Date.now() - start } },\n    timestamp: new Date().toISOString(),\n  });\n}\n```\n\n## Redirect URI Configuration\n\nAfter deploying, update your Canva integration settings with the production redirect URI:\n\n| Platform | Redirect URI Pattern |\n|----------|---------------------|\n| Vercel | `https:\u002F\u002Fyour-app.vercel.app\u002Fauth\u002Fcanva\u002Fcallback` |\n| Fly.io | `https:\u002F\u002Fyour-app.fly.dev\u002Fauth\u002Fcanva\u002Fcallback` |\n| Cloud Run | `https:\u002F\u002Fyour-service-xxxxx.run.app\u002Fauth\u002Fcanva\u002Fcallback` |\n| Custom Domain | `https:\u002F\u002Fapp.yourdomain.com\u002Fauth\u002Fcanva\u002Fcallback` |\n\n## Error Handling\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| OAuth callback fails | Redirect URI mismatch | Update URI in Canva dashboard |\n| Secret not found | Missing env var | Add via platform CLI |\n| Cold start timeout | OAuth exchange slow | Set min instances to 1 |\n| HTTPS required | HTTP redirect URI | All platforms default to HTTPS |\n\n## Resources\n\n- [Canva Creating Integrations](https:\u002F\u002Fwww.canva.dev\u002Fdocs\u002Fconnect\u002Fcreating-integrations\u002F)\n- [Vercel Docs](https:\u002F\u002Fvercel.com\u002Fdocs)\n- [Fly.io Docs](https:\u002F\u002Ffly.io\u002Fdocs)\n- [Cloud Run Docs](https:\u002F\u002Fcloud.google.com\u002Frun\u002Fdocs)\n\n## Next Steps\n\nFor webhook handling, see `canva-webhooks-events`.\n\n",{"name":5,"tags":54,"author":56,"license":15,"version":57,"description":58,"allowed-tools":59,"compatible-with":60},[55,48,31],"saas","Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Deploy Canva Connect API integrations to Vercel, Fly.io, and Cloud Run.\nUse when deploying Canva-powered applications to production,\nconfiguring platform-specific secrets, or setting up deployment pipelines.\nTrigger with phrases like \"deploy canva\", \"canva Vercel\",\n\"canva production deploy\", \"canva Cloud Run\", \"canva Fly.io\".\n","Read, Write, Edit, Bash(vercel:*), Bash(fly:*), Bash(gcloud:*)","claude-code","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fcanva-deploy-integration",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill canva-deploy-integration",{"tool":76,"command":77},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill canva-deploy-integration",{"tool":79,"command":80},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill canva-deploy-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fcanva-deploy-integration\u002FSKILL.md",true,[],[85,97,107,116,122,129],{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":93,"publishedAt":49},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[90],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[94,95,96],"model","model hierarchy","model hierarchy skill",{"skillNo":98,"name":99,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":103,"publishedAt":49},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[102],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},[104,105,106],"MCP","zoom","zoom mcp",{"skillNo":108,"name":109,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":49},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[113,114,115,105],"sdk","zoom apps sdk","apps",{"skillNo":117,"name":118,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":49},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[118],{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":128,"publishedAt":49},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[127],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},[124],{"skillNo":130,"name":131,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":49},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[131]]