# Så lagrar du data i en AI-byggd app med Supabase

> Varje app du bygger i NorthernGo får automatiskt en Supabase-databas i PostgreSQL. Här är det exakta API:t för att spara, läsa och radera poster, plus hur du lägger till inloggning per användare.

Source: https://northerngo.com/sv/guider/lagra-data-med-supabase/
Language: sv
Updated: 2026-08-22

---
**Appar byggda i NorthernGo behöver ingen databaskoppling — varje genererad app har redan en Supabase-databas i PostgreSQL inkopplad via ett globalt objekt som heter `window.NorthernGoDB`. Du sparar en post med `await window.NorthernGoDB.save(kollektion, data)` och läser tillbaka den med `await window.NorthernGoDB.get(kollektion)`. Det finns inget schema att definiera och ingen anslutningssträng att klistra in.**

### Databasen finns redan där

Det vanligaste missförståndet om AI-appbyggare är att du måste ta med dig en egen backend. I NorthernGo behöver du inte det. Varje app som genereras får en databasbrygga injicerad i sig innan du ens ser koden, kopplad till en delad Supabase-instans i PostgreSQL som ligger inom EU.

Bryggan exponeras som ett enda globalt objekt, `window.NorthernGoDB`. AI-agenterna som skriver din app känner redan till det och använder det som standard, vilket betyder att om du helt enkelt ber om "en att göra-lista som kommer ihåg vad jag skrivit" så sparar den genererade appen redan datan korrekt. Du behöver bara förstå API:t om du vill ändra i koden själv, eller om du vill veta vad som faktiskt händer under ytan.

Det finns ingen tabell att skapa i förväg. Kollektioner skapas första gången du sparar något i dem, och det är medvetet — schemamigrering är precis den sortens arbete som får den som inte är utvecklare att aldrig bli klar med sitt projekt.

### Steg 1: Spara din första post

`save()` tar ett kollektionsnamn och ett vanligt objekt. Objektet får ha vilken form du vill, och kollektionen behöver inte finnas sedan tidigare.

```javascript
await window.NorthernGoDB.save('uppgifter', {
  text: 'Handla mjölk',
  klar: false,
  skapad: new Date().toISOString()
});
```

Anropet returnerar ett promise, så det hör hemma i en `async`-funktion och bör omslutas av `try/catch`. En misslyckad skrivning utan felhantering är den absolut vanligaste orsaken till att en genererad app verkar "tappa" data — posten kom aldrig fram och ingenting sa till.

```javascript
async function laggTillUppgift(text) {
  try {
    await window.NorthernGoDB.save('uppgifter', { text, klar: false });
    await renderaUppgifter();
  } catch (err) {
    console.error(err);
    visaMeddelande('Kunde inte spara. Kontrollera uppkopplingen och försök igen.');
  }
}
```

### Steg 2: Läs tillbaka datan

`get()` tar ett kollektionsnamn och returnerar en array med posterna i den. Anropa den en gång när sidan laddas och sedan igen efter varje skrivning, så att gränssnittet alltid speglar vad som faktiskt är lagrat.

```javascript
window.addEventListener('DOMContentLoaded', async () => {
  try {
    const uppgifter = await window.NorthernGoDB.get('uppgifter');
    renderaUppgifter(uppgifter || []);
  } catch (err) {
    console.error(err);
    renderaUppgifter([]);
  }
});
```

Notera reservvärdet `|| []`. En tom kollektion kan returnera något annat än en array, och renderingskod som utgår från att det är en array kastar fel i en helt ny app utan data. Det här är det näst vanligaste felet i genererade appar, och det ger det värsta symtomet: en helt vit skärm vid första besöket.

### Steg 3: Radera poster

`delete()` tar kollektionen plus ett fältnamn och värdet som ska matchas, i stället för ett internt rad-id. Det gör den användbar från vanlig appkod, där du i regel känner till saken du vill ta bort men inte dess databasnyckel.

```javascript
await window.NorthernGoDB.delete('uppgifter', 'text', 'Handla mjölk');
```

Matchar flera poster på fältet och värdet tas alla bort — så matcha på något genuint unikt när det spelar roll. Att spara en egen identifierare vid skrivning är det pålitliga tillvägagångssättet:

```javascript
const id = crypto.randomUUID();
await window.NorthernGoDB.save('uppgifter', { id, text, klar: false });
await window.NorthernGoDB.delete('uppgifter', 'id', id);
```

### Steg 4: Ge varje användare sin egen data

Allt ovan lagrar data på appnivå: varje besökare ser samma poster. Så snart du vill att människor ska ha privat data behöver appen inloggning, och samma objekt hanterar även det.

```javascript
await window.NorthernGoDB.register(epost, losenord);
await window.NorthernGoDB.login(epost, losenord);
const arInloggad = !!window.NorthernGoDB.getToken();
window.NorthernGoDB.logout();
```

Autentiseringen sker medvetet med e-post och lösenord. När en användare är inloggad stämplar plattformen varje skyddad skrivning med hens identitet, och `get()` returnerar bara hens rader. Du skriver inte filtret själv, och du ska inte sätta fältet `_ngOwner` — servern skriver över det. Det vanliga mönstret är att kontrollera `getToken()` vid start och visa antingen inloggningsformuläret eller själva appen.

Delade kollektioner mellan inloggade (ett team-CRM, en intern tavla) hoppar över isoleringen med `{ shared: true }`. Publika kataloger, menyer och highscore-listor använder `false` så att gäster kan läsa utan konto:

```javascript
await window.NorthernGoDB.save('kontakter', kontakt, { shared: true });
const allaKontakter = await window.NorthernGoDB.get('kontakter', { shared: true });

await window.NorthernGoDB.save('produkter', produkt, false);
const katalogen = await window.NorthernGoDB.get('produkter', false);
```

En app-admin (`role: 'admin'`) ser alla rader i appen. Det är kontot som skapas med `setupAdmin`.

En sak är inte valfri: en app med inloggning måste också ha ett synligt sätt att radera kontot. Det är [GDPR artikel 17](/sv/guider/gdpr-compliant-app-building-eu/), inte en trevlig extrafunktion, och SDK:n ger dig ett enda anrop för det.

```javascript
if (confirm('Detta raderar ditt konto och all din data permanent. Fortsätta?')) {
  await window.NorthernGoDB.deleteAccount();
  location.reload();
}
```

Bygg inte en egen raderingsrutt med `fetch` och försök inte rensa användaren genom att anropa `delete()` i en loop. `deleteAccount()` tar bort autentiseringsposten och den tillhörande datan tillsammans; en hemsnickrad variant lämnar med säkerhet något kvar.

### Spegla datan till ett system du styr själv

Det finns en separat funktion i arbetsytan som heter **Egen Databas**, och det är värt att vara exakt med vad den gör, eftersom namnet antyder något den inte är.

Den byter inte ut den inbyggda Supabase-databasen mot en egen, och den tar inte emot en Supabase-anslutningssträng. Den tar en HTTP-endpoint. När den är satt skickas varje skrivning dina appar gör även som en POST till den URL:en, i JSON:

```json
{
  "projectId": "abc123",
  "collection": "uppgifter",
  "data": { "text": "Handla mjölk", "klar": false },
  "timestamp": "2026-08-15T09:12:44.000Z"
}
```

Det gör den till en spegling, inte en ersättning. Den är genuint användbar för att mata in appdata i ditt eget datalager, ett scenario i Zapier eller Make, ett internt CRM eller en Fortnox-integration — men appen fortsätter läsa från den inbyggda databasen oavsett. Behöver du en helt fristående backend är det ärliga svaret att [exportera källkoden](/sv/guider/avoid-vendor-lock-in-ai-builders/) och peka om den själv.

### Vad det här inte ger dig

Att vara tydlig med gränserna sparar mer tid än någon funktionslista.

- **Ingen SQL.** Du kan inte skriva joins, aggregeringar eller vyer mot kollektionerna från appkoden. API:t är medvetet fyra metoder brett.
- **Inga realtidsprenumerationer.** Det finns ingen lyssnare som utlöses när en annan användare skriver. Behöver du liveuppdateringar får du polla med ett intervall.
- **Köade offlineskrivningar, senast kända läsningar.** På en publicerad PWA köas `save()`/`delete()` utan nät i SDK:n och spelas upp när appen är online. `get()` returnerar senast lyckade lista plus väntande rader. Inloggning, betalning, e-post och AI misslyckas fortfarande utan uppkoppling. Se [guiden om offline först](/sv/guider/offline-first-web-apps-pwa/).
- **Ingen schemakontroll.** Ingenting hindrar dig från att spara `{ text: 'x' }` i en post och `{ titel: 'x' }` i nästa. Konsekvensen är ditt ansvar.

### Felsökning

**Datan sparas men försvinner vid omladdning.** Nästan alltid skriver appen till `localStorage` i stället för till databasen. Sök i den genererade koden efter `localStorage.setItem` — hamnar appdata där finns den bara på en enhet och försvinner när cachen rensas. Be AI:n flytta lagringen till `window.NorthernGoDB`.

**Vit skärm vid första laddningen.** Renderingsfunktionen fick något annat än en array från en tom kollektion. Lägg till reservvärdet `|| []` och omslut inläsningen med `try/catch`.

**Skrivningar gör tyst ingenting.** Kontrollera att anropet är awaitat. `window.NorthernGoDB.save(...)` utan `await` i en async-funktion hinner ofta bli klar först efter att sidan redan navigerat eller renderats om.

**Alla användare ser allas data.** Det är förväntat utan inloggning, och för kollektioner som sparas med `false` (publikt) eller `{ shared: true }` (gemensam inloggad data). Privata poster bakom inloggning isoleras automatiskt; ser två kunder fortfarande varandra skickar den genererade koden `false` eller `shared: true` på den kollektionen.

## Vanliga frågor

### Behöver jag ett eget Supabase-konto för att bygga en app med databas?

Nej. Varje app som genereras i NorthernGo är redan kopplad till en Supabase-databas i PostgreSQL som ligger inom EU, via objektet window.NorthernGoDB. Det finns inget konto att skapa, ingen anslutningssträng att klistra in och ingen tabell att definiera i förväg.

### Kan jag koppla in min egen externa databas i stället?

Inte som en ersättning. Inställningen Egen Databas tar en HTTP-endpoint och speglar varje skrivning dit som JSON, så datan når ditt eget system, men appen fortsätter läsa från den inbyggda databasen. För att köra helt på egen backend exporterar du källkoden och pekar om den själv.

### Varför tappar min app datan när jag laddar om sidan?

Nästan alltid för att appen skriver till localStorage i stället för till databasen. Data i localStorage finns bara i den enskilda webbläsaren på den enskilda enheten och försvinner när cachen rensas. Sök i koden efter localStorage.setItem och flytta all appdata till window.NorthernGoDB.save.

### Kan två användare se varandras data?

Utan inloggning, ja — poster lagras på appnivå och alla ser samma kollektion. Lägger du till register och login via window.NorthernGoDB stämplas varje skyddad skrivning till den användaren, så att samma get-anrop bara returnerar hens egen data. Skicka { shared: true } för team-kollektioner, eller false för en publik katalog.

### Fungerar databasen när appen är offline?

På en publicerad PWA, ja för data: get() visar senast synkad lista plus köade sparningar, och save/delete spelas upp när appen är online igen. Inloggning, betalning, e-post och AI i appen kräver fortfarande uppkoppling. Väntande rader märks _pending: true.

---

## Related

- [Så bygger du en webbapp som fungerar utan internet](https://northerngo.com/sv/guider/offline-appar-med-pwa/)
- [Bygga GDPR-säkra appar: en praktisk checklista för EU-grundare](https://northerngo.com/sv/guider/bygga-gdpr-saker-app/)
- [Så undviker du inlåsning när du bygger med en AI-appbyggare](https://northerngo.com/sv/guider/undvik-inlasning-ai-verktyg/)
- [Så exporterar du en AI-byggd app till ett nativt iOS- och Android-projekt med Capacitor](https://northerngo.com/sv/guider/exportera-till-ios-och-android/)

---

NorthernGo är en AI-driven plattform för att bygga produktionsklara webbappar utan kod. Lokal AI-generering via WebGPU är obegränsad och gratis, och du äger all genererad källkod. https://northerngo.com/
