Skip to content

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âmpScop
NumeVariabila 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ă.
ValoareDoar 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ă:

ȘabloaneCitește cu
React, ReactTS, Vue, VueTS, Svelte, SolidJS, SolidTS, VanillaJS, VanillaTS, React Native, React Native TSimport.meta.env.VITE_NAME
SvelteKit, SvelteKit TS, Remix, Remix TSimport.meta.env.VITE_NAME (client) · process.env.NAME (cod server)
Next.js, Next.js TSprocess.env.NAME (Server Components, rute API)
Astro, AstroTSimport.meta.env.NAME
Angularimport { DOJOCODE_ENV } from './dojocode-env'; apoi DOJOCODE_ENV['NAME']
NodeJS, NodeTS, Fastify, Hono, NestJSprocess.env.NAME
Pythonos.environ["NAME"]
JavaSystem.getenv("NAME")
C#System.Environment.GetEnvironmentVariable("NAME")
Cgetenv("NAME")
C++std::getenv("NAME")
Goos.Getenv("NAME")
Ruststd::env::var("NAME")
RubyENV["NAME"]
PHPgetenv('NAME')
Solidityvm.envString("NAME")
PGlite, SQLiteNu 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. În previzualizare acest lucru este sigur: ea rulează întotdeauna doar propriile tale valori pe propria ta origine temporară. Un proiect de browser publicat e altă poveste — vezi Secretele și publicarea.

jsx
export default function App() {
  return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
vue
<script setup>
const apiKey = import.meta.env.VITE_API_KEY;
</script>

<template>
  <h1>Key: {{ apiKey }}</h1>
</template>
svelte
<h1>Key: {import.meta.env.VITE_API_KEY}</h1>
jsx
export default function App() {
  return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
js
document.querySelector('#app').textContent = import.meta.env.VITE_API_KEY;
jsx
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 ​

tsx
// src/app/page.tsx — Server Components and API routes read process.env
export default function Home() {
  return <h1>Key: {process.env.API_KEY}</h1>;
}
astro
---
const apiKey = import.meta.env.API_KEY;
---
<h1>Key: {apiKey}</h1>
svelte
<!-- src/routes/+page.svelte -->
<h1>Key: {import.meta.env.VITE_API_KEY}</h1>
<!-- In +page.server.js / hooks, use process.env.API_KEY -->
tsx
// 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_KEY

Angular ​

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.

ts
// 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:

js
console.log(process.env.API_KEY);

Python ​

python
import os

print(os.environ["API_KEY"])          # raises KeyError if unset
print(os.environ.get("API_KEY"))      # None if unset

Limbaje compilate și altele ​

Aceste șabloane rulează în panoul Output (butonul Run); secretele sunt injectate în mediul de rulare.

java
public class HelloWorld {
    public static String hello() {
        return System.getenv("API_KEY");
    }
}
csharp
namespace Challenge
{
    public class HelloWorld
    {
        public static string Hello()
        {
            return System.Environment.GetEnvironmentVariable("API_KEY");
        }
    }
}
c
#include <stdlib.h>
#include <stdio.h>

void print() {
    printf("%s\n", getenv("API_KEY"));
}
cpp
#include <cstdlib>
#include <iostream>

int main() {
    std::cout << std::getenv("API_KEY") << std::endl;
}
go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getenv("API_KEY"))
}
rust
fn main() {
    println!("{}", std::env::var("API_KEY").unwrap_or_default());
}
ruby
puts ENV["API_KEY"]
php
<?php
echo getenv('API_KEY');
solidity
// 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 proiect publicat (*.dojocode.net) nu are un vizitator autentificat, așa că rulează cu valorile tale: fiecare secret de proiect pe care l-ai declarat, plus acele secrete ale contului tău la care codul face referire prin nume. Ce înseamnă asta pentru tine depinde de locul în care rulează proiectul.

Aplicații de server — valorile rămân pe server ​

Next.js, SvelteKit, Remix, NestJS, Fastify, Hono, NodeJS și proiectele Python cu testerul de API pornit se publică drept server live. Secretele tale ajung la acel server ca variabile de mediu — exact ce citesc process.env.NAME sau os.environ["NAME"] — și nu fac niciodată parte din ce descarcă browserul unui vizitator. Nimeni nu le poate citi din pagină.

Două lucruri de ținut minte:

  • Oricine are linkul îți folosește cheile. Fiecare cerere declanșată de un vizitator rulează cu cheia ta API, iar furnizorul ție îți facturează. Ai grijă cui trimiți linkul și preferă chei cu limită de cheltuieli.
  • Citește-le în codul de server. În SvelteKit și Remix, aliasul VITE_ (import.meta.env.VITE_NAME) există doar în previzualizarea din editor. O aplicație publicată este construită fără el, astfel încât codul ei de browser nu primește niciodată un secret — citește process.env.NAME în loadere, acțiuni și rute de server și trimite browserului doar rezultatul.

Modificarea sau ștergerea unui secret ajunge și la aplicația live: următoarea cerere o repornește cu valorile noi, fără republicare. O aplicație de server primește în total cel mult 32 KB de valori secrete.

Site-uri statice — valorile devin publice ​

React, Vue, Svelte, SolidJS, VanillaJS, Angular, Astro și proiectele Python care rulează în browser se publică drept site static: nu există server, întregul proiect rulează în browserul vizitatorului. Ca să poată folosi codul un secret acolo, valoarea lui trebuie inclusă în pagina publicată — unde oricine deschide linkul o poate citi și o poate folosi în altă parte.

Publici pe propriul risc

Caseta de dialog Publish afișează secretele care ar fi expuse. Publică un site static cu secrete doar dacă fiecare dintre ele poate fi public fără probleme — o cheie restricționată, cu limită mică sau gratuită. Pentru orice costă bani sau oferă acces, mută apelul într-un șablon de server.

Pe un site static valorile sunt fixate în momentul publicării: după ce schimbi un secret, republică proiectul ca modificarea să se aplice.

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ă.