Port @sanity/studio-secrets plugin to monorepo#568
Conversation
update Sanity UI, safer type for empty query
feat: use tagged requests
npx @sanity/plugin-kit@1.1.0-ecosystem-preset.5 inject --preset semver-workflow --preset renovatebot
Co-authored-by: RitaDias <6951139+RitaDias@users.noreply.github.com>
Co-authored-by: RitaDias <6951139+RitaDias@users.noreply.github.com>
The useState initializer only runs once at mount. Since useSecrets starts
with loading: true and secrets: undefined, the initial value was always {}.
Without the useEffect, the settings dialog shows empty fields on cold load
because newSecrets never updates when secrets load from the API.
…Record<string, any> Reverts the type narrowing introduced by the port. The original code used Record<string, any> and narrowing to string is a public API change that should not be made without deliberate intent. Added oxlint-disable comments for the any usage.
… unused oxlint directives Replace useEffect with useRef-based 'adjust state during render' pattern to satisfy the react-hooks-js(set-state-in-effect) lint rule. Remove unused oxlint-disable-next-line directives for @typescript-eslint/no-explicit-any which oxlint does not enforce in this monorepo.
…cret sync, fix changeset Replace useRef pattern (blocked by react-hooks-js/refs) with useEffect + oxlint-disable-next-line for react-hooks-js/set-state-in-effect. This is a legitimate useEffect for external async data sync, not the cascading render anti-pattern the rule targets. Also fix changeset: remove inaccurate claim about useEffect removal being a React Compiler requirement.
pedrobonamin
left a comment
There was a problem hiding this comment.
🤖 AI-Generated Review
This review was generated by AI agents @Quartz and @facet in a head-to-head review competition, judged by @Compass. The findings were challenged and verified by a human reviewer before posting.
PR #568 Review Feedback
Port @sanity/studio-secrets to Monorepo
Recommendation: Approve with suggestions ✅
Summary
The migration is well-executed. The core functionality is preserved, the public API is faithfully maintained, monorepo patterns are followed correctly, and React Compiler compatibility fixes are solid. There are no blockers—just some cosmetic issues and optional improvement opportunities.
Suggested Fixes (Cosmetic)
1. Fix README Example Placeholder 🟡
Location: README.md
Problem: The example code has an obvious placeholder:
<SettingsView
title={'sdfds'} // ← Should be a real exampleFix: Replace with something like 'Configure API Settings' or 'My Plugin Settings'.
2. Fix Dialog ID Copy-Paste Artifact 🟡
Location: Settings.tsx
Problem:
<Dialog animate id="translation-settings" onClose={onClose} header={title}>The ID "translation-settings" appears to be copied from another plugin.
Fix: Change to "studio-secrets-settings" or similar.
Documentation Suggestions
3. Document @sanity/incompatible-plugin Removal
The original package included @sanity/incompatible-plugin as a dependency for graceful degradation on older Sanity versions. This was removed in the migration. Consider adding a note to the changeset explaining this was intentional for the v5+ target.
4. Document v2 Compatibility Files Removal
The original repo had v2-incompatible.js and sanity.json for Sanity v2 compatibility. These were correctly omitted (v5+ target), but explicitly noting this in the changeset would be helpful.
5. Migration Path for Breaking Peer Deps
The changeset notes the peer dependency changes, but consider adding guidance for users migrating from:
- React 18 → React 19
- Sanity 3.x/4.x → Sanity 5.x
Optional Improvements (API Enhancements)
Since this is a major version bump, consider improving the public API surface. These are pre-existing gaps in the original plugin, not regressions—but this would be a good time to fix them:
6. Consider Exporting Secrets<T> Interface
The useSecrets hook returns a Secrets<T> object, but this interface isn't exported. Adding it would allow consumers to properly type the hook's return value:
// Add to index.ts exports:
export type {Secrets} from './useSecrets'7. Consider Exporting SettingsKey Type
The SettingsKey type is needed by consumers to properly type their keys array:
// Add to index.ts exports:
export type {SettingsKey} from './Settings'What's Already Good ✅
- Git history preservation - All 87 commits maintained via subtree
- Monorepo structure - Correctly follows patterns from PR #493
- React Compiler compatibility - useRef pattern instead of sync useEffect
- TypeScript modernization - FormEvent → ChangeEvent, JSX.Element → ReactElement
- Test studio integration - Working demo in kitchen-sink workspace
- Floating promise fixes - void operator applied correctly
- Node engines field - Matches monorepo standard
Summary Table
| Issue | Severity | Action |
|---|---|---|
README placeholder 'sdfds' |
🟡 Cosmetic | Should fix |
Dialog ID "translation-settings" |
🟡 Cosmetic | Should fix |
| Document incompatible-plugin removal | 🟢 Info | Recommended |
| Document v2 files removal | 🟢 Info | Recommended |
Add SettingsKey export |
🟢 Info | Optional improvement |
Add Secrets<T> export |
🟢 Info | Optional improvement |
…ate call) The disable-next-line directive must be directly above the setNewSecrets() call inside the effect, not above the useEffect itself. Matches the pattern used in sanity-plugin-workflow/useWorkflowDocuments.tsx.
| @@ -0,0 +1,21 @@ | |||
| MIT License | |||
|
|
|||
| Copyright (c) 2025 Sanity.io | |||
There was a problem hiding this comment.
Updated to 2026 in 3a1057d. Also fixed the README placeholder ('sdfds' → 'My Plugin Settings') and Dialog ID ("translation-settings" → "studio-secrets-settings") noted in the AI review.
| "prepack": "turbo run build" | ||
| }, | ||
| "dependencies": { | ||
| "@sanity/ui": "^2.10.10" |
…log ID Co-authored-by: pedrobonamin <46196328+pedrobonamin@users.noreply.github.com>
Co-authored-by: pedrobonamin <46196328+pedrobonamin@users.noreply.github.com>
pnpm generate "copy plugin"to set up the plugin workspace with git subtreeSummary
Successfully ported
@sanity/studio-secretsplugin to the monorepo with a working test studio example.Test Studio Example
The example adds a "Secrets Demo" tool to the kitchen-sink workspace that demonstrates:
useSecretshook to read secretsSettingsViewcomponent to configure secretsTo try it out:
Then navigate to http://localhost:3333/kitchen-sink and click the "Secrets Demo" tool (🔒 icon) in the toolbar.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.