@remotion/studio: Add "Licensing" tab for adding remotion.pro key#6164
@remotion/studio: Add "Licensing" tab for adding remotion.pro key#6164JonnyBurger merged 16 commits intomainfrom
@remotion/studio: Add "Licensing" tab for adding remotion.pro key#6164Conversation
…n-dev/remotion into web-render-modal-license
There was a problem hiding this comment.
Pull request overview
This PR adds a "Licensing" tab to the Remotion Studio that allows users to configure their license key (either the free license or a company license key). The changes integrate license key management across the Studio UI, CLI, and web renderer.
- Adds a new "License" tab in the WebRenderModal with options for Free License and Company License
- Implements license key validation (format checking for public license keys starting with "rm_pub_")
- Integrates license key into rendering APIs (renderMediaOnWeb and renderStillOnWeb) for telemetry
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/studio/src/components/RenderModal/WebRenderModalLicense.tsx | New component implementing the license configuration UI with validation |
| packages/studio/src/components/RenderModal/WebRenderModal.tsx | Integrates the license tab and passes license key to rendering functions |
| packages/studio/src/components/Checkbox.tsx | Adds support for rounded checkboxes used in the license UI |
| packages/studio/src/state/modals.ts | Adds initialLicenseKey to WebRenderModalState |
| packages/studio/src/components/RenderButton.tsx | Passes initial license key from defaults |
| packages/studio/src/components/Modals.tsx | Threads initialLicenseKey to WebRenderModal |
| packages/studio/src/icons/certificate.tsx | New certificate icon for the license tab |
| packages/studio/src/helpers/inject-css.ts | Removes border-radius override from color picker focus styles |
| packages/renderer/src/options/public-license-key.tsx | Defines the publicLicenseKey option with validation logic |
| packages/renderer/src/options/index.tsx | Exports the publicLicenseKeyOption |
| packages/cli/src/config/index.ts | Adds setPublicLicenseKey to Config object |
| packages/cli/src/parse-command-line.ts | Parses --license-key and --public-license-key flags |
| packages/cli/src/get-render-defaults.ts | Adds publicLicenseKey to render defaults |
| packages/studio-shared/src/render-defaults.ts | Adds publicLicenseKey field to RenderDefaults type |
| packages/web-renderer/src/send-telemetry-event.ts | Updates error message to use "Free License" (capitalized) |
| packages/web-renderer/src/render-media-on-web.tsx | Adds sendUsageEvent calls with license key for telemetry |
| packages/docs/docs/config.mdx | Documents the setPublicLicenseKey() config option |
| packages/docs/docs/cli/studio.mdx | Documents the --public-license-key CLI flag |
Comments suppressed due to low confidence (1)
packages/web-renderer/src/render-media-on-web.tsx:444
- The sendUsageEvent function appears to be called twice for successful renders - once for webFsTarget at lines 421-425 and once for BufferTarget at lines 440-444. However, when webFsTarget is truthy, the function returns early at line 433, so the second call won't be reached. The duplication is misleading and should be restructured to avoid confusion. Consider extracting the sendUsageEvent call to a single location before the conditional returns.
sendUsageEvent({
licenseKey: licenseKey ?? null,
succeeded: true,
apiName: 'renderMediaOnWeb',
});
await webFsTarget.close();
return {
getBlob: () => {
return webFsTarget.getBlob();
},
internalState,
};
}
if (!(target instanceof BufferTarget)) {
throw new Error('Expected target to be a BufferTarget');
}
sendUsageEvent({
licenseKey: licenseKey ?? null,
succeeded: true,
apiName: 'renderMediaOnWeb',
});
| /> | ||
| <div style={box}>{checked ? <Checkmark /> : null}</div> | ||
| <div style={box}> | ||
| {checked ? rounded ? <div style={bullet} /> : <Checkmark /> : null} |
There was a problem hiding this comment.
The nested ternary operator is difficult to read and understand. Consider restructuring this logic for better clarity. For example, extract the logic into a separate function or use explicit conditional blocks.
| if ( | ||
| parsedCli['license-key'] && | ||
| parsedCli['license-key'].startsWith('rm_pub_') | ||
| ) { |
There was a problem hiding this comment.
The handling of 'license-key' is inconsistent with 'public-license-key'. The 'license-key' flag only sets the value if it starts with 'rm_pub_', while 'public-license-key' always sets it. Consider either removing the conditional check for 'license-key' (since setPublicLicenseKey already validates the format) or applying the same check to both flags for consistency.
| if ( | |
| parsedCli['license-key'] && | |
| parsedCli['license-key'].startsWith('rm_pub_') | |
| ) { | |
| if (parsedCli['license-key']) { |
TODO: