Secretele proiectului
Construiești ceva care comunică cu un API real? Vei avea nevoie de o cheie API — iar adăugarea ei direct în cod este o idee proastă: proiectele pot fi partajate, bifurcate (forked) și sunt vizibile pentru oricine are linkul.
Secretele rezolvă această problemă. Un secret este o pereche nume + valoare (de exemplu OPENAI_API_KEY = sk-…) pe care DojoCode o stochează criptată și o injectează în runtime-ul proiectului tău ca variabilă de mediu. Codul tău citește numele; valoarea nu apare niciodată în fișierele tale, în editor sau pentru altcineva.
Doar scriere prin design
Odată salvată, valoarea unui secret nu mai poate fi vizualizată niciodată — nici de tine, nici de alți utilizatori, nici de Asistentul AI. Poți doar să o înlocuiești sau să o ștergi. Dacă uiți o valoare, setează una nouă.
Cum funcționează secretele
- Două domenii de aplicare. Secretele de cont (globale) sunt ale tale peste tot — fiecare proiect pe care îl deschizi le poate folosi. Secretele de proiect sunt declarate pentru un singur proiect.
- Proiectul suprascrie globalul. Dacă un secret de proiect și un secret de cont au același nume, valoarea din proiect are prioritate în cadrul acelui proiect.
- Fiecare vine cu propriile valori. Atunci când un alt utilizator îți deschide proiectul, acesta furnizează propriile valori pentru secretele de care are nevoie proiectul tău. Valorile tale nu sunt niciodată partajate — secretele sunt private per utilizator și per proiect.
- Criptate în repaus (at rest), injectate la runtime. Valorile sunt criptate AES în baza de date și decriptate doar atunci când codul tău rulează efectiv — în previzualizarea din browser sau în sandbox-ul de rulare (Run).
Secretele de cont (Setări)
Gestionează-ți secretele globale din Setări cont → Secrete — ultima filă de pe pagina ta de setări.
Fiecare secret are:
| Câmp | Scop |
|---|---|
| Nume | Variabila de mediu pe care o citește codul tău, de ex. OPENAI_API_KEY. |
| Descriere (opțional) | Scopul secretului. De asemenea, este afișată Asistentului AI, astfel încât acesta să știe că secretul există — valoarea nu este afișată niciodată. |
| Valoare | Doar scriere. Afișată ca •••••••• de atunci încolo. |

Apasă pe New secret (Secret nou), oferă-i un nume, o descriere opțională și valoarea — asta este tot:

Secretele de proiect (fila Secrete)
Fiecare editor de proiect — atât în pagina de editare, cât și în cea de vizualizare — are o filă Secrete lângă Detalii.
În calitate de autor al proiectului (pagina de editare): secretele pe care le adaugi aici devin cerințe ale proiectului. Acestea suprascriu secretele de cont cu același nume, iar oricui deschide proiectul i se va cere să furnizeze propriile valori pentru aceste nume. Ștergerea unui secret îl elimină din cerințele proiectului și șterge valoarea salvată a fiecărui utilizator pentru acesta.

În calitate de vizitator (pagina de vizualizare): fila Secrete arată numele declarate de autor, dacă ai configurat o valoare pentru fiecare, și îți permite să adaugi secrete suplimentare proprii pentru acest proiect — chiar dacă autorul nu a declarat niciunul. Dacă un nume solicitat se potrivește cu unul dintre secretele tale de cont, acesta este completat automat.

Dacă proiectul necesită secrete pe care nu le-ai setat, un mesaj de notificare îți va propune să deschizi fila Secrete. Poți să treci peste — secretele nesetate sunt pur și simplu undefined la runtime:

Oaspeții nu pot deschide proiecte care folosesc secrete — este necesară autentificarea:

Reguli de denumire și limite
- Numele încep cu o literă sau cu
_și pot conține litere, cifre și caractere de subliniere. Numele sunt sensibile la majuscule și minuscule (case-sensitive) —OPENAI_API_KEY,apiKey,_internal_token. - Prefixe rezervate pe care nu le poți folosi:
DOJOCODE_,VITE_DOJOCODE_,NODE_,NPM_,PATH. - Până la 100 de secrete de cont și 100 de secrete per proiect; valori de până la 8 KB.
Citirea secretelor în codul tău
Modul în care citești un secret depinde de runtime-ul șablonului. Referință rapidă:
| Șabloane | Citește cu |
|---|---|
| React, ReactTS, Vue, VueTS, Svelte, SolidJS, SolidTS, VanillaJS, VanillaTS, React Native, React Native TS | import.meta.env.VITE_NAME |
| SvelteKit, SvelteKit TS, Remix, Remix TS | import.meta.env.VITE_NAME (client) · process.env.NAME (cod server) |
| Next.js, Next.js TS | process.env.NAME (Server Components, rute API) |
| Astro, AstroTS | import.meta.env.NAME |
| Angular | import { DOJOCODE_ENV } from './dojocode-env'; apoi DOJOCODE_ENV['NAME'] |
| NodeJS, NodeTS, Fastify, Hono, NestJS | process.env.NAME |
| Python | os.environ["NAME"] |
| Java | System.getenv("NAME") |
| C# | System.Environment.GetEnvironmentVariable("NAME") |
| C | getenv("NAME") |
| C++ | std::getenv("NAME") |
| Go | os.Getenv("NAME") |
| Rust | std::env::var("NAME") |
| Ruby | ENV["NAME"] |
| PHP | getenv('NAME') |
| Solidity | vm.envString("NAME") |
| PGlite, SQLite | Nu este disponibil — mediile de testare (playgrounds) SQL nu au un runtime care să citească variabilele de mediu. |
Toate exemplele de mai jos presupun un secret numit API_KEY.
Browser templates (Vite)
Codul din browser poate vedea doar variabilele prefixate cu VITE_, așa că DojoCode expune fiecare secret și sub un alias VITE_ de asemenea. Acest lucru este sigur, deoarece previzualizarea rulează întotdeauna doar propriile tale valori pe propria ta origine temporară — iar proiectele care folosesc secrete nu pot fi publicate.
export default function App() {
return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}<script setup>
const apiKey = import.meta.env.VITE_API_KEY;
</script>
<template>
<h1>Key: {{ apiKey }}</h1>
</template><h1>Key: {import.meta.env.VITE_API_KEY}</h1>export default function App() {
return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}document.querySelector('#app').textContent = import.meta.env.VITE_API_KEY;import { View, Text } from 'react-native';
export default function App() {
return (
<View>
<Text>Key: {import.meta.env.VITE_API_KEY}</Text>
</View>
);
}Full-stack templates
// src/app/page.tsx — Server Components and API routes read process.env
export default function Home() {
return <h1>Key: {process.env.API_KEY}</h1>;
}---
const apiKey = import.meta.env.API_KEY;
---
<h1>Key: {apiKey}</h1><!-- src/routes/+page.svelte -->
<h1>Key: {import.meta.env.VITE_API_KEY}</h1>
<!-- In +page.server.js / hooks, use process.env.API_KEY -->// app/routes/_index.tsx
export default function Index() {
return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
// In loaders/actions (server), use process.env.API_KEYAngular
Angular nu are în procesul de build un mecanism pentru variabile de mediu, așa că DojoCode montează un modul virtual numit dojocode-env.ts în rădăcina proiectului ori de câte ori ai secrete. Acesta apare ca read-only în arborele de fișiere, astfel încât să poți vedea ce nume există — valorile din interior sunt completate doar în previzualizarea care rulează, niciodată în editor.
// app.component.ts
import { Component } from '@angular/core';
import { DOJOCODE_ENV } from './dojocode-env';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
apiKey = DOJOCODE_ENV['API_KEY'];
}ATENȚIE
Nu crea și nu edita niciodată singur dojocode-env.ts — platforma se ocupă de gestionarea acestuia și nu este salvat niciodată în proiectul tău.
Backend JavaScript templates
Funcționează la fel în NodeJS, NodeTS, Fastify, Hono și NestJS:
console.log(process.env.API_KEY);Python
import os
print(os.environ["API_KEY"]) # raises KeyError if unset
print(os.environ.get("API_KEY")) # None if unsetLimbaje compilate și altele
Aceste șabloane rulează în panoul Output (butonul Run); secretele sunt injectate în mediul de rulare.
public class HelloWorld {
public static String hello() {
return System.getenv("API_KEY");
}
}namespace Challenge
{
public class HelloWorld
{
public static string Hello()
{
return System.Environment.GetEnvironmentVariable("API_KEY");
}
}
}#include <stdlib.h>
#include <stdio.h>
void print() {
printf("%s\n", getenv("API_KEY"));
}#include <cstdlib>
#include <iostream>
int main() {
std::cout << std::getenv("API_KEY") << std::endl;
}package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Getenv("API_KEY"))
}fn main() {
println!("{}", std::env::var("API_KEY").unwrap_or_default());
}puts ENV["API_KEY"]<?php
echo getenv('API_KEY');// In a Foundry script (Main.s.sol)
import "forge-std/Script.sol";
import "forge-std/console.sol";
contract Main is Script {
function run() external {
console.log(vm.envString("API_KEY"));
}
}Playground-uri SQL
Șabloanele PGlite și SQLite execută doar fișiere .sql — nu există cod de utilizator care să poată citi o variabilă de mediu, prin urmare secretele nu sunt disponibile acolo, iar fila Secrets este ascunsă.
Secretele și publicarea
Un site publicat (*.dojocode.net) este un build static, public — orice valoare secretă utilizată în timpul build-ului ar ajunge să fie lizibilă în bundle. Pentru a-ți păstra cheile în siguranță, publicarea este blocată atunci când un proiect folosește secrete:
- proiectul declară secrete de proiect, sau
- codul său face referire la oricare dintre numele de secrete ale contului tău.
Caseta de dialog Publish explică exact ce nume blochează publicarea și rămâne blocată până când elimini referințele (sau le redenumești). Variabilele de deployment setate de proprietar sunt planificate pentru o versiune viitoare.

Secretele și Alex (asistentul AI)
Alex vede numele și descrierile secretelor disponibile pentru proiect — niciodată valorile. În acest fel, poate scrie cod care citește process.env.API_KEY pentru tine, se poate asigura că tratează valorile lipsă și te poate direcționa către panoul Secrets atunci când o funcționalitate are nevoie de o cheie pe care nu ai adăugat-o încă. Va refuza să scrie direct în cod valori secrete sau să scrie fișiere .env, deoarece acestea ar fi salvate în proiect pentru a fi văzute de toată lumea.
Bine de știut
- Săritul peste pas este permis. Un vizitator care omite solicitarea de introducere a secretelor poate rula în continuare proiectul — secretele nesetate sunt doar
undefined/goale la runtime, așa că asigură-te că tratezi valorile lipsă. - Fork-urile nu copiază secretele. Fă un fork unui proiect și acesta va începe de la zero; declară din nou ceea ce are nevoie.
- Actualizarea păstrează vechea valoare dacă o lași goală. Editarea descrierii unui secret fără a tasta o nouă valoare lasă valoarea stocată neschimbată.
- Previzualizarea se repornește automat atunci când secretele se modifică, astfel încât noile valori sunt preluate fără o reîncărcare manuală.