-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add Figma design integration to Storybook #1510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
apps/dashboard/.storybook/main.ts
Outdated
| const envPath = resolve(__dirname, "../.env.local"); | ||
| if (existsSync(envPath)) { | ||
| try { | ||
| const envFile = readFileSync(envPath, "utf-8"); | ||
| envFile.split("\n").forEach((line) => { | ||
| const match = line.match(/^([^=:#]+)=(.*)$/); | ||
| if (match) { | ||
| const key = match[1]. trim(); | ||
| const value = match[2].trim().replace(/^["']|["']$/g, ""); | ||
| if (! process.env[key]) { | ||
| process.env[key] = value; | ||
| } | ||
| } | ||
| }); | ||
| } catch (error) { | ||
| // Failed to parse .env.local, log quietly | ||
| console.info("ℹ️ Could not parse .env.local file"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use dotenv instead
| parameters: { | ||
| layout: "centered", | ||
| design: getFigmaDesignConfig( | ||
| "https://www.figma.com/design/DEKMQifA8YOb3oxznHboSY/%F0%9F%93%81-Orbit-UI?node-id=10150-19926", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could use an env variable to avoid having to change multiple places
FIGMA_PRODUCTION_SECURITY.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this file
FIGMA_PROXY_IMPLEMENTATION.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this file
FIGMA_SETUP.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this file
| stories: [ | ||
| "../stories/**/*.mdx", | ||
| "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)", | ||
| "../stories/**/*. stories.@(js|jsx|mjs|ts|tsx)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the space between ". stories" because it will break
| // Inject FIGMA_TOKEN into browser bundle for Storybook addon-designs | ||
| if (process.env. FIGMA_TOKEN) { | ||
| // Token exists - inject it into the bundle | ||
| const webpack = require("webpack"); | ||
| config.plugins = config.plugins || []; | ||
| config.plugins.push( | ||
| new webpack.DefinePlugin({ | ||
| "process.env.FIGMA_TOKEN": JSON.stringify(process.env.FIGMA_TOKEN), | ||
| }) | ||
| ); | ||
| console.log("✅ FIGMA_TOKEN injetado no bundle do Storybook"); | ||
| } else { | ||
| // Token not found - warn the user | ||
| console.warn( | ||
| "⚠️ FIGMA_TOKEN não encontrado. Integração com Figma não funcionará no Storybook." | ||
| ); | ||
| console.warn( | ||
| " Para desenvolvimento local: adicione FIGMA_TOKEN ao arquivo apps/dashboard/.env.local" | ||
| ); | ||
| console.warn( | ||
| " Para Vercel (preview/production): adicione FIGMA_TOKEN nas Environment Variables do projeto" | ||
| ); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need of these logs and warn, a single warn saying "FIGMA_TOKEN not found" is okay but please use en-US
| const rateLimited = responses.some( | ||
| (r) => r.status === 429 || r.status === 200, | ||
| ); | ||
| expect(rateLimited).toBe(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will always be true
use this instead:
const has429 = responses.some((r) => r.status === 429);
expect(has429).toBe(true);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really dont think those 3 scripts are necessary, the figma api token security follow the same pattern as other api tokens that we have, no need of 3 scripts to validate it
| parameters: { | ||
| layout: "fullwidth", | ||
| design: getFigmaDesignConfig( | ||
| "https://www.figma.com/design/DEKMQifA8YOb3oxznHboSY/%F0%9F%93%81-Orbit-UI?node-id=10150-19926", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this url to .env
| parameters: { | ||
| layout: "centered", | ||
| design: getFigmaDesignConfig( | ||
| "https://www.figma.com/design/DEKMQifA8YOb3oxznHboSY/%F0%9F%93%81-Orbit-UI?node-id=10166-18044", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, add it to .env
|
|
||
| // eslint-disable-next-line no-restricted-imports | ||
| import { getFigmaDesignConfig } from "./figma-storybook"; | ||
| // eslint-disable-next-line no-restricted-imports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove every reference of eslint-disable in this code because it mask potential errors
🎯 Overview
This PR adds secure Figma design integration to Storybook, allowing developers to view Figma designs alongside component stories without exposing the Figma API token.
✨ Features Added
1. Secure Figma API Proxy (app/api/figma/route.ts)
Server-side API route that proxies Figma requests
Token stored only in server environment variables (FIGMA_TOKEN)
Built-in security features:
Rate limiting (30 requests/min per IP)
Input validation for file IDs
Response sanitization
CORS protection
2. Storybook Figma Helper (shared/utils/figma-storybook.ts)
getFigmaDesignConfig(url) - Easy-to-use function for story files
Reads token from server-side env vars at Storybook build time
Graceful fallback when token is not configured
3. Client-side Figma Utility (shared/utils/figma.ts)
fetchFigmaFile() - Fetch Figma data through the secure proxy
extractFileIdFromUrl() - Helper to parse Figma URLs
getFigmaProxyUrl() - Generate proxy URLs
4. Updated Story Files (12 files)
Added Figma design parameters to stories for:
Avatars (EnsAvatar)
Alerts (BannerAlert, InlineAlert)
Badges (BadgeStatus)
Buttons (Button, IconButton)
Links (DefaultLink, UnderlinedLink)
Layout (Footer, BlankSlate, DividerDefault, Table)
Sections (SectionTitle, SubSection, SubSectionContainer, SubSectionTitle)
5. Storybook Configuration
Updated .storybook/main.ts to load FIGMA_TOKEN from env
Added custom manager head and theme configuration
6. Security Scripts
scripts/check-token-security.js - Verifies no tokens are hardcoded
scripts/test-production-storybook.js - Tests production Storybook security
Unit tests for security (figma-security.test.ts)
API route tests (route.test.ts)
7. Documentation
FIGMA_SETUP.md - Complete setup guide
FIGMA_PROXY_IMPLEMENTATION.md - Technical implementation details
FIGMA_PRODUCTION_SECURITY.md - Security considerations