Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
dac0502
CrowdIn Module Commit
sushilzore Aug 26, 2025
2ebe7d0
CrowdIn Module Fixes
sushilzore Sep 10, 2025
02bd019
Yarn Lock File CHanges
sushilzore Sep 10, 2025
c4dbaf8
Crowdin Plugin Change
sushilzore Sep 10, 2025
cd5af6a
Crowdin plugin changes
sushilzore Sep 11, 2025
6bc5ce6
bump version
clementroche Sep 10, 2025
331f2f4
TypeScript Error Fixes
sushilzore Sep 11, 2025
d8bfc08
TypeScript Fixes
sushilzore Sep 11, 2025
5f78a0a
Corrected the Error Message
sushilzore Sep 11, 2025
00631ba
CrowdIn Export Fixes
sushilzore Sep 12, 2025
95689f7
TypeScript Fixes
sushilzore Sep 12, 2025
c70d819
TypeScript Fixes
sushilzore Sep 12, 2025
1ee7d3b
TypeScript Fixes
sushilzore Sep 12, 2025
0949416
TypeScript Fixes
sushilzore Sep 12, 2025
d567e86
CrowdIn Language Related Fixes
sushilzore Sep 15, 2025
067bd13
UI height
clementroche Sep 15, 2025
cd00388
New UI provided As Per Mock Up
sushilzore Sep 25, 2025
49719ab
fix yarn
clementroche Oct 2, 2025
6e17f42
assets
clementroche Oct 2, 2025
88eead2
cleanup
clementroche Oct 3, 2025
c1e34f3
readme
clementroche Oct 3, 2025
8a686a4
pass TS CI
clementroche Oct 3, 2025
4845360
pass TS CI again
clementroche Oct 3, 2025
f64f4a8
Update plugins/crowdin/src/App.tsx
clementroche Oct 6, 2025
4be53ea
Update plugins/crowdin/src/xliff.ts
clementroche Oct 6, 2025
f559ef6
UI QA
clementroche Oct 6, 2025
7ab4bda
invalid access token
clementroche Oct 6, 2025
7e36b88
conditional renderin plugin
clementroche Oct 6, 2025
f7fccfa
pass ts CI
clementroche Oct 6, 2025
ed8bfc0
button theme
clementroche Oct 7, 2025
0b5ce40
check permissions
clementroche Oct 7, 2025
1bcfb78
improve error managment
clementroche Oct 7, 2025
4a22fd8
QA
clementroche Oct 9, 2025
f4e06f7
Update framer-plugin
madebyisaacr Jan 28, 2026
53887b6
Update CSS and logo
madebyisaacr Jan 28, 2026
37bc862
Add link
madebyisaacr Jan 28, 2026
c1d5232
Loading states and validation
madebyisaacr Jan 28, 2026
c2984fd
Update notifications
madebyisaacr Jan 28, 2026
4ec1615
Errors and validation
madebyisaacr Jan 28, 2026
ef975bb
Light theme logo, fix import error
madebyisaacr Jan 28, 2026
3d9b521
Close warning
madebyisaacr Jan 28, 2026
0bdaf73
Add code
madebyisaacr Jan 28, 2026
01c8f6a
Fix padding
madebyisaacr Jan 28, 2026
ed1bf5c
Auto focus
madebyisaacr Jan 28, 2026
e96b091
Update image
madebyisaacr Jan 29, 2026
57f88d6
Logo
madebyisaacr Jan 29, 2026
fb20b20
Text
madebyisaacr Jan 29, 2026
03023d3
Remove unused code
madebyisaacr Jan 29, 2026
415afcc
Update index.html
madebyisaacr Jan 29, 2026
79eb3b7
Update dependency
madebyisaacr Jan 29, 2026
89db06f
New home page
madebyisaacr Jan 29, 2026
84aaa35
Config page
madebyisaacr Jan 29, 2026
fb6dbc9
New app design
madebyisaacr Jan 29, 2026
3c1bc84
Improve validation
madebyisaacr Jan 29, 2026
2ba3511
Locale selector
madebyisaacr Jan 29, 2026
9f26cc5
Buttons
madebyisaacr Jan 29, 2026
41d580e
Error state
madebyisaacr Jan 29, 2026
f8e27c1
Move icons
madebyisaacr Jan 29, 2026
6332b27
Make buttons work
madebyisaacr Jan 29, 2026
8ddf371
Delete OldApp.tsx
madebyisaacr Jan 29, 2026
9c83469
Update App.css
madebyisaacr Jan 29, 2026
e5619bb
Remove unused svg
madebyisaacr Jan 29, 2026
fc5eb3d
Projects menu
madebyisaacr Jan 29, 2026
1bd171a
Improve locale selection
madebyisaacr Jan 29, 2026
14ec4e9
Locales list
madebyisaacr Jan 29, 2026
5dbd64a
Sync multiple locales
madebyisaacr Jan 29, 2026
371d7b1
Empty state
madebyisaacr Jan 29, 2026
807fcde
Fix token saving
madebyisaacr Jan 29, 2026
daba70c
Confirmation modal
madebyisaacr Jan 29, 2026
e7d9939
Close on import
madebyisaacr Jan 29, 2026
997b2bd
Revert close on import
madebyisaacr Jan 29, 2026
a6bcf7b
Fix formatting
madebyisaacr Jan 29, 2026
bdb61a8
Locales loading state
madebyisaacr Jan 30, 2026
d3454c9
Save selected project
madebyisaacr Jan 30, 2026
341275a
autoComplete off
madebyisaacr Jan 30, 2026
1cd0333
Add link, update empty states
madebyisaacr Jan 30, 2026
2678aa9
No locales message
madebyisaacr Jan 31, 2026
2358169
Allow opening when no locales found
madebyisaacr Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file added assets/crowdin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions plugins/crowdin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Crowdin Localization Plugin for Framer

A Framer plugin that synchronizes localization strings between **Framer** and **[Crowdin](https://crowdin.com/)**.
---

## ✨ Features
- **Export** source strings from Framer → Crowdin
- **Import** translations from Crowdin → Framer
- Simple UI with **two buttons**:
- `Export to Crowdin`
- `Import from Crowdin`


**By:** @sushilzore, @clementroche, and @madebyisaacr

![Crowdin Image](../../assets/hero.png)
6 changes: 6 additions & 0 deletions plugins/crowdin/framer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "cr0d1n",
"name": "Crowdin",
"modes": ["localization"],
"icon": "/icon.svg"
}
13 changes: 13 additions & 0 deletions plugins/crowdin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Crowdin</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions plugins/crowdin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "crowdin",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "run g:dev",
"build": "run g:build",
"check-biome": "run g:check-biome",
"check-eslint": "run g:check-eslint",
"preview": "run g:preview",
"pack": "npx framer-plugin-tools@latest pack",
"check-typescript": "run g:check-typescript"
},
"dependencies": {
"@crowdin/crowdin-api-client": "^1.46.0",
"classnames": "^2.5.1",
"framer-plugin": "^3.10.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"valibot": "^1.2.0"
},
"devDependencies": {
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.7"
}
}
12 changes: 12 additions & 0 deletions plugins/crowdin/public/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
254 changes: 254 additions & 0 deletions plugins/crowdin/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
/* Your Plugin CSS */

:root {
--crowdin-brand-color: #263238;
--color-error: #ff3366;
}

[data-framer-theme="light"] {
--image-border-color: rgba(0, 0, 0, 0.05);
}

[data-framer-theme="dark"] {
--image-border-color: rgba(255, 255, 255, 0.05);
}

main {
display: flex;
flex-direction: column;
align-items: start;
padding: 0 15px 15px;
gap: 15px;

user-select: none;
-webkit-user-select: none;
}

main.home {
height: 270px;
}

select {
padding: 0 16px 0 10px;
}

select:not(:disabled) {
cursor: pointer;
}

h1 {
font-size: 12px;
font-weight: 600;
}

strong {
font-weight: 500;
color: var(--framer-color-text);
}

.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
gap: 10px;
width: 100%;
flex: 1;
}

.hero p {
text-wrap: balance;
color: var(--framer-color-text-tertiary);
max-width: 200px;
}

.hero .logo {
width: 30px;
height: 30px;
border-radius: 8px;
position: relative;
overflow: clip;
margin-bottom: 5px;
}

.hero .logo img {
width: 100%;
height: 100%;
}

.hero .logo:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid var(--image-border-color);
border-radius: 8px;
}

.button-row {
display: flex;
flex-direction: row;
gap: 10px;
width: 100%;
}

.button-row button {
flex: 1;
}

.controls-stack {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}

.property-control {
width: 100%;
display: flex;
flex-direction: row;
align-items: start;
gap: 10px;
padding-left: 10px;
}

.property-control.disabled > p,
.controls-stack.disabled {
opacity: 0.5;
pointer-events: none;
}

.property-control > p {
flex: 1;
height: 30px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

.property-control .content {
display: flex;
flex-direction: column;
gap: 10px;
width: 150px;
}

.property-control .content > * {
width: 100%;
}

.access-token-input {
position: relative;
}

.access-token-input input {
width: 100%;
}

.access-token-input:has(.icon) input {
padding-right: 26px;
}

.access-token-input .icon-button {
position: absolute;
top: 0;
right: 0;
}

.link-icon:hover {
color: var(--framer-color-text);
}

.access-token-input .icon {
position: absolute;
padding: 0 8px;
height: 100%;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
}

.button-stack {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}

.dropdown-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 10px;
width: 100%;
padding-right: 0;
font-weight: 500;
background-color: var(--framer-color-bg-tertiary) !important;
}

.icon-button {
display: flex;
align-items: center;
justify-content: center;
padding: 0 8px;
height: 100%;
color: var(--framer-color-text-tertiary);
transition: color 0.2s ease-in-out;
}

input.error {
box-shadow: inset 0 0 0 1px var(--color-error);
color: var(--color-error);
background-color: color-mix(in srgb, var(--color-error) 10%, transparent);
}

.locales-empty-state {
background-color: var(--framer-color-bg-tertiary);
border-radius: 8px;
opacity: 0.5;
height: 30px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 0 10px;
}

.checkbox-label {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
}

.checkbox-label input[type="checkbox"]:not(:checked) {
background-color: var(--framer-color-bg-tertiary);
}

.heading {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}

.step-indicator {
color: var(--framer-color-text-tertiary);
}

.no-locales-message {
width: 100%;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
color: var(--framer-color-text-tertiary);
}
Loading
Loading