Anjali Ariscrisnã
Admilson Cruz

6 augusti 2026

Min läsning

Användning av ramverket Next.js med TypeScript

Next.js-logotyp tillsammans med TypeScript-logotyp på vit bakgrund, som visar hur Next.js och TypeScript fungerar tillsammans.

Två verktyg, två helt olika problem. Ramverket Next.js löser ett renderingsproblem: att leverera färdig HTML till sökmotorer och användare utan att ge avkall på interaktiviteten i en React-app. TypeScript löser något helt annat, nämligen att definiera datastrukturen innan en enda rad kod körs.

Så bör du använda båda? Endast under en förutsättning: att din kodbas kommer att överleva teamet som skrev den. Det är hela testet, och vi kommer att återkomma till det. Först, vad varje verktyg faktiskt gör, och sedan hur du kopplar ihop dem.

blå pil till vänster
Imaginary Cloud-logotyp

Vad är ramverket Next.js?

Next.js är ett ramverk med öppen källkod skapat av Vercel. Det marknadsförs som ett utvecklingspaket för webben med alla verktyg som behövs för att göra webben snabbare. Lär dig mer om Next.js-funktioner med React och dess användningsområden här.

Vad används Next.js till?

Next.js gör det möjligt för sökmotorer att optimera React-appar med minimal ansträngning från din sida. Föreställ dig vad en traditionell React-app skickar först: ett HTML-skal utan något renderat innehåll.

Webbläsaren hämtar sedan JavaScript-filen som innehåller din React-kod, renderar innehållet i DOM:en – webbläsarens levande träd av sidelement – och gör det interaktivt. Det fungerar, men har två nackdelar som är värda att ta på allvar:

  • Innehållet indexeras inte alltid tillförlitligt av alla sökmotorer och läses inte heller korrekt av länkbottar i sociala medier. Googles egen dokumentation förklarar varför JavaScript-renderade sidor kräver en extra bearbetningsomgång innan de kan indexeras.
  • Det kan ta längre tid att nå den första innehållsrika renderingen (First Contentful Paint), det vill säga ögonblicket då webbläsaren visar det första faktiska innehållet på skärmen istället för ett tomt skal.

Next.js låter dig bygga en React-app men rendera innehållet i förväg på servern, så att det första en användare eller en sökrobot ser är färdigrenderad HTML. När den första sidan väl har laddats tar klient-side rendering över och appen fungerar som vilken annan React-app som helst.

Färdigrenderat innehåll för robotar. Höginteraktivt innehåll för användare. En enda kodbas.

Datahämtning på klientsidan med ramverket Next.js

Datahämtning är där ramverket Next.js verkligen visar sitt värde, eftersom det kan köra flera olika strategier för serverrendering från ett och samma projekt.

Datahämtning på klientsidan passar sidor som inte behöver SEO-indexering, inte kräver förrenderad data eller ändras för ofta för att det ska vara värt att låsa dem. Statisk generering, även kallat förrendering, bygger dina sidor en gång vid byggtillfället istället för vid varje anrop. Här är versionen för klientsidan:

import { useEffect, useState } from 'react';

type Todo = { id: number; text: string; done: boolean };

export default function TodoList() {
  const [isLoading, setIsLoading] = useState(true);
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    fetch('/api/todos')
      .then((response) => response.json())
      .then((data: Todo[]) => {
        setTodos(data);
        setIsLoading(false);
      });
  }, []);

  if (isLoading) return <p>Loading...</p>;

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

Det där är datahämtning på klientsidan med Reacts useEffect hook. Vi initierar två konstanter, en för att hålla koll på om hämtningen fortfarande pågår och en för att lagra resultatet, och anropar sedan useEffect med två argument:

  • Callback – funktionen som innehåller logiken för sidoeffekten som körs direkt efter att ändringar har skickats till DOM:en. Här hämtar den logiken data från en slutpunkt och sparar den i vår konstant.
  • Beroenden – en array som anger när callback-funktionen ska köras. En tom array innebär att den körs en gång.

En detalj värd att notera. Att Todo[] -annoteringen på svaret är ett löfte, inte en garanti: den talar om för kompilatorn vad du förväntar dig att slutpunkten ska skicka tillbaka, och ingenting kontrollerar detta vid körning. Senare skriver vi själva API-rutten, så att löftet efterlevs i båda ändar.

blå pil till vänster
Imaginary Cloud-logotyp

Vad är TypeScript?

TypeScript är ett programmeringsspråk som utvecklas och underhålls av Microsoft. Det är en strikt övermängd av JavaScript, vilket innebär att varje giltig JavaScript-fil redan är giltig TypeScript. Du behöver inte konvertera någonting från dag ett.

Se det som att märka upp flyttkartonger när du flyttar. Du kan flytta utan etiketter, och förr eller senare kommer du att upptäcka vad som finns i varje låda. TypeScript är märkpennan: det har stöd för statisk och dynamisk typning, lägger till funktioner för arv, klasser och gränssnitt, och skapades för större projekt eftersom det gör koden betydligt enklare att refaktorera. Läs mer om dess funktioner i en djupgående jämförelse med JavaScript.

blå pil till vänster
Imaginary Cloud-logotyp

Vad använder du TypeScript till i ett Next.js-projekt?

Det finns många anledningar till att en JavaScript-utvecklare väljer att byta:

  • Användning av nya ECMAScript-funktioner – TypeScript har stöd för aktuella ECMAScript-standarder och transpilerar dem, vilket innebär att de konverteras till en äldre syntax som webbläsare redan förstår. Skriv moduler, pilfunktioner och destrukturering, och leverera kod som körs i äldre webbläsare.
  • Statisk typning – JavaScript är dynamiskt typat och vet inte vad en variabel innehåller förrän den instansieras vid körning. TypeScript flyttar den kontrollen till kompileringstillfället.
  • Typinferens – kompilatorn räknar ut en variabels typ baserat på värdet du tilldelar den, så du behöver skriva färre annoteringar än du kanske tror. Även de typer du aldrig skrev ut finns där och fångar upp det som annars hade blivit ett körningsfel.
  • Bättre IDE-stöd – typer driver autokomplettering, hopp-till-definition och säker omdöpning. Visual Studio och VS Code, IntelliJ, Sublime och WebStorm har alla inbyggt stöd för TypeScript.
  • Strikt null-kontroll – "you cannot read a property 'x' of undefined" är det mest välbekanta felet i JavaScript. Strikt kontroll fångar upp de flesta fel av den typen, eftersom du inte kan använda en variabel som kompilatorn inte känner till.
  • Interoperabilitet – TypeScript ligger tillräckligt nära JavaScript för att fungera med hela dess ekosystem, även om bibliotek utan typer behöver typdeklarationer för att kompilatorn ska kunna hjälpa dig med dem.

Typsäkerhet är en leveransdisciplin bland flera. Om du ser över hur ditt team arbetar från början till slut, täcker vår guide till de 18 bästa agila metoderna för din mjukvaruutvecklingscykel resten.

Banner: 18 bästa agila metoderna inom mjukvaruutveckling med kvinna som håller i kom-ihåg-lappar för SaaS-app.
blå pil till vänster
Imaginary Cloud-logotyp

Bör du använda ramverket Next.js med TypeScript?

Det tekniska argumentet är väl dokumenterat. Det kommersiella argumentet är det som faktiskt avgör saken, och det är värt att reda ut innan någon skriver en tsconfig.json.

Vi kallar vår kontroll för överlevnadstestet: tre frågor om huruvida en kodbas kommer att överleva personerna som skrev den. Kör dem på ditt eget projekt.

1. Var upptäcks dina defekter? Ett typfel fångas upp av kompilatorn, direkt i utvecklarens editor, sekunder efter att det skrivits. Samma misstag i vanlig JavaScript väntar till körtid, vilket i praktiken innebär QA, staging eller produktion. Varje steg i den kedjan kostar mer att diagnostisera och mer att åtgärda. Det sista steget kostar dig en release.

Den kategorin är mätbar, vilket är ovanligt för den här typen av argument. Airbnb granskade sina egna tidigare incidenter under sin migrering och rapporterade vid JSConf Hawaii 2019 att 38 procent av buggarna de levererat hade kunnat förhindras med TypeScript. En oberoende studie, To Type or Not to Type: Quantifying Detectable Bugs in JavaScript (Gao, Bird och Barr, ICSE 2017), samplade offentliga buggfixar från GitHub och satte siffran till 15 procent. Betrakta det lägre talet som ditt golv och det högre som hur en stor, långlivad kodbas ser ut.

2. Hur snabbt kan en främling ändra din kod? I en ärvd kodbas är typer den dokumentation som inte kan bli inaktuell. En utvecklare som ansluter till ett typat Next.js-projekt följer en prop från en sida in i en komponent och ser exakt vad den innehåller. I ett otypat projekt läser de anropsplatserna, gissar, och får vid granskningen veta om gissningen höll.

3. Vad kostar det att ändra kodbasen under år tre? Det är här TypeScript verkligen lönar sig. Att byta namn på ett fält eller ändra formen på ett API-svar blir en kompilatorstyrd uppgift istället för en manuell sökning genom hela arkivet. Det spelar enorm roll för en långlivad produkt, men knappt någon alls för en marknadsföringssida med en livslängd på sex månader.

Vår regel på Imaginary Cloud följer direkt av testet. Om en kodbas kommer att överleva teamet som skrev den, startar vi den i TypeScript. Om det är en prototyp som ska kastas bort gör vi det oftast inte, eftersom startkostnaden är verklig och utdelningen aldrig kommer.

blå pil till vänster
Imaginary Cloud-logotyp

Hur installerar jag TypeScript i ett Next.js-projekt?

Här är en steg-för-steg-guide för TypeScript i en Next.js-app, från en tom mapp till en typsäker sida. Guiden använder Pages Router, vilket är vad de flesta befintliga produktionskodbaser fortfarande körs på. Avsnittet om App Router nedan täcker den nyare modellen.

Syftet med denna genomgång är inte själva att-göra-appen. Det är det typsäkra kontraktet mellan API-rutten och sidan som anropar den – den del som de flesta guider hoppar över, och som är den del som verkligen lönar sig.

1. Skapa basprojektet. Kör npx create-next-app@latest my-todo-app för att skapa ett projekt från grundmallen.

2. Lägg till tsconfig.json i projektets rotmapp för att aktivera TypeScript. Next.js upptäcker filen nästa gång du kör npm run dev, installerar de TypeScript-beroenden som behövs och fyller i filen åt dig. En genererad konfiguration ser ut så här:

{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [{ "name": "next" }],
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

Låt strict vara aktiverat. Att stänga av det är det absolut vanligaste sättet för ett team att hamna med en kodbas som visserligen har typer, men som inte fångar upp några fel. Raden plugins aktiverar Next.js språkserver-plugin för TypeScript, och paths -aliaset är det som gör @/… import-upplösning – exemplen för App Router nedan förlitar sig på den.

3. Strukturera projektet enligt nedan.

my-todo-app/
├── app/                      # App Router (see the section below)
│   └── api/
│       └── todos/
│           └── route.ts
├── components/
│   ├── TodoForm.tsx
│   └── TodoItem.tsx
├── pages/                    # Pages Router (this walkthrough)
│   ├── api/
│   │   └── todos.ts
│   ├── _app.tsx
│   └── index.tsx
├── types/
│   └── todo.ts
├── next-env.d.ts
├── package.json
└── tsconfig.json

4. Skapa TypeScript-typer i Next.js.

Du kan ange typer för allt i din applikation: props, API-svar och funktionsargument. Placera de typer som korsar en gräns i en egen fil, eftersom det är det som gör dem delbara.

Börja med en typ för vår Todo:

// types/todo.ts
export type Todo = {
  id: number;
  text: string;
  done: boolean;
};

5. Ange typ för API-rutten med samma typ.

Detta är steget som förvandlar TypeScript från en bekvämlighet i editorn till ett kontrakt. Rutt-hanteraren deklarerar att den returnerar Todo[]. Sidan som anropar den deklarerar att den tar emot Todo[]. Båda läser från samma fil.

// pages/api/todos.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { Todo } from '../../types/todo';

const todos: Todo[] = [
  { id: 1, text: 'Type the API route', done: true },
  { id: 2, text: 'Ship it', done: false },
];

export default function handler(
  _request: NextApiRequest,
  response: NextApiResponse<Todo[]>
) {
  response.status(200).json(todos);
}

Utdelningen kommer den dag någon döper om text till label i types/todo.ts. Rutt-hanteraren slutar kompilera, eftersom objekten i todos stämmer inte längre Todo[], och det gör även alla komponenter som läser todo.text. Utan den delade typen? Omdöpningen kompilerar utan problem och sidan renderar tyst en kolumn med tomma rader.

6. Skapa komponenter i Next.js.

Nu när vi har vår Todo-typ kan vi bygga TodoItem-komponenten.

// components/TodoItem.tsx
import { Todo } from '../types/todo';

type TodoItemProps = {
  todo: Todo;
  removeTodo: (id: number) => void;
  setDone: (id: number) => void;
};

export default function TodoItem({ todo, removeTodo, setDone }: TodoItemProps) {
  return (
    <li>
      <input
        type="checkbox"
        checked={todo.done}
        onChange={() => setDone(todo.id)}
      />
      <span>{todo.text}</span>
      <button onClick={() => removeTodo(todo.id)}>Remove</button>
    </li>
  );
}

Vi importerar typen vi skapade och deklarerar sedan en till, TodoItemProps, som speglar de props som komponenten tar emot.

Den här komponenten visar ett Todo-objekt. Den tar emot objektet, en removeTodo -funktion och en setDone -funktion som props. Argumentet måste matcha props-typen, annars avvisar kompilatorn det innan koden ens körs.

Nu till TodoForm-komponenten, som ansvarar för att lägga till att-göra-objekt.

// components/TodoForm.tsx
import { FormEvent, useState } from 'react';

type TodoFormProps = {
  addTodo: (text: string) => void;
};

export default function TodoForm({ addTodo }: TodoFormProps) {
  const [value, setValue] = useState('');

  const handleSubmit = (event: FormEvent) => {
    event.preventDefault();
    if (!value.trim()) return;
    addTodo(value);
    setValue('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={value} onChange={(event) => setValue(event.target.value)} />
      <button type="submit">Add todo</button>
    </form>
  );
}

Den accepterar en addTodo -funktion som en prop och hanterar inskickning av ett nytt att-göra-objekt. Om värdet inte är tomt anropar den addTodo med texten och rensar formuläret.

Titta på signaturen för den prop: (text: string) => void. Föräldrakomponenten kan inte skicka en funktion som förväntar sig ett objekt, eller en som förväntar sig två argument, utan att kompilatorn har synpunkter på det.

7. Skapa sidan som använder komponenterna.

Vi importerar komponenterna och typerna från tidigare, plus GetStaticProps, en typ från Next.js som låter oss typa getStaticProps -metoden, funktionen som Next.js kör vid byggtiden för att hämta den data som en statiskt genererad sida behöver.

Sedan initierar vi todos-tillståndet med useState -hooken, där vi skickar in de initiala todos som getStaticProps tillhandahåller, och deklarerar de tre funktionerna som innehåller vår logik:

  • addTodo – lägger till en todo i listan
  • removeTodo – tar bort en todo från listan
  • setDone – markerar en att göra-uppgift som utförd

Slutligen renderar vi listan med hjälp av våra komponenter.

// pages/index.tsx
import { GetStaticProps } from 'next';
import { useState } from 'react';
import TodoForm from '../components/TodoForm';
import TodoItem from '../components/TodoItem';
import { Todo } from '../types/todo';

type HomeProps = {
  initialTodos: Todo[];
};

export default function Home({ initialTodos }: HomeProps) {
  const [todos, setTodos] = useState<Todo[]>(initialTodos);

  const addTodo = (text: string) =>
    setTodos([...todos, { id: Date.now(), text, done: false }]);

  const removeTodo = (id: number) =>
    setTodos(todos.filter((todo) => todo.id !== id));

  const setDone = (id: number) =>
    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, done: !todo.done } : todo
      )
    );

  return (
    <main>
      <TodoForm addTodo={addTodo} />
      <ul>
        {todos.map((todo) => (
          <TodoItem
            key={todo.id}
            todo={todo}
            removeTodo={removeTodo}
            setDone={setDone}
          />
        ))}
      </ul>
    </main>
  );
}

export const getStaticProps: GetStaticProps<HomeProps> = async () => {
  const response = await fetch('http://localhost:3000/api/todos');
  const initialTodos: Todo[] = await response.json();

  return { props: { initialTodos }, revalidate: 60 };
};

En viktig notering gällande hämtningen: att anropa det egna API:et via HTTP vid byggtiden är sårbart, eftersom servern kanske inte körs när sidan genereras. I ett faktiskt bygge bör du importera datakällan direkt inuti getStaticProps istället för att gå via nätverket.

Sidan är nu typad från början till slut, från route-hanterare via props till renderat element. Ändra strukturen för Todo i types/todo.ts så pekar kompilatorn ut varje fil som inte längre stämmer, innan du ens har öppnat en webbläsare.

blå pil till vänster
Imaginary Cloud-logotyp

App Router och TypeScript

Allt ovan använder Pages Router. Sedan Next.js 13 har App Router varit standard för nya projekt, och från och med Next.js 16 (oktober 2025) är det standarden som ramverket är byggt kring – Turbopack är nu standardbundler och minimikravet är Node.js 20. Typmodellen förändras med App Router. Startar du ett projekt idag? Det är den här versionen du ska använda.

Tre saker ändras:

  • Sidor blir serverkomponenter. En sida i app/ körs som standard på servern och kan vara en async-funktion, vilket gör att datahämtning sker inline. Ingen getStaticProps, inget props-objekt att typa: du skriver typer för det du hämtar, där du hämtar det.
  • API-rutter blir route handlers. pages/api/todos.ts blir app/api/todos/route.ts, där du exporterar en funktion uppkallad efter HTTP-metoden och använder webbens Request och Response -objekt istället för de Next.js-specifika.
  • Cachning ersätter valet av renderingsläge. getStaticProps med revalidate blir ett alternativ direkt i fetch-anropet. Samma delade typ omfattar fortfarande båda ändar.

Vad har ändrats i Next.js 16

Om du senast arbetade med Next.js kring version 13 eller 14 finns det tre saker som är värda att känna till innan du uppgraderar. Turbopack är nu standard för både utveckling och bygge, vilket gör att kallstarter och ombyggnationer går betydligt snabbare, och de flesta projekt utan anpassad webpack-konfiguration behöver inte göra några ändringar. Den lägsta versionen av Node.js som stöds är 20. Dessutom är cachemodellen nu explicit: fetch cachas inte längre som standard, så du väljer att aktivera det per anrop med cache och next.revalidate istället för att förlita dig på ramverkets standardinställningar. Inget av detta ändrar mönstret för typade kontrakt i den här artikeln — types/todo.ts är fortfarande den enda definitionen som båda ändar delar — men det ändrar kommandona du kör. Uppgraderings-codemoden (npx @next/codemod@latest upgrade latest) sköter det mesta av det mekaniska arbetet; avsätt tid för migreringen till App Router och kompatibilitet med React 19, snarare än själva versionsuppdateringen.

// app/api/todos/route.ts
import { NextResponse } from 'next/server';
import { Todo } from '@/types/todo';

const todos: Todo[] = [
  { id: 1, text: 'Type the route handler', done: true },
  { id: 2, text: 'Ship it', done: false },
];

export async function GET() {
  return NextResponse.json<Todo[]>(todos);
}
// app/page.tsx
import TodoItem from '@/components/TodoItem';
import { Todo } from '@/types/todo';

async function getTodos(): Promise<Todo[]> {
  const response = await fetch('http://localhost:3000/api/todos', {
    next: { revalidate: 60 },
  });
  return response.json();
}

export default async function Home() {
  const todos = await getTodos();

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

Samma kontrakt som tidigare: types/todo.ts är den enda definitionen, routhanteraren deklarerar att den returnerar den strukturen, och sidan deklarerar att den förbrukar den. En varning innan du migrerar något. Interaktiva komponenter som TodoForm behöver 'use client' -direktivet högst upp i filen, eftersom tillstånd och händelsehanterare inte kan köras på servern.

blå pil till vänster
Imaginary Cloud-logotyp

Vanliga frågor

Är det värt att använda Next.js med TypeScript?

För alla applikationer som du förväntar dig att underhålla i mer än några månader, ja. Next.js har inbyggt stöd för TypeScript i toppklass, så startkostnaden är nästan noll, och typsäkerheten ger utdelning vid varje refaktorering och för varje ny utvecklare som ansluter till projektet.

Kan jag lägga till TypeScript i ett befintligt Next.js-projekt?

Ja, och du kan göra det stegvis. Lägg till en tsconfig.json -fil, starta utvecklingsservern, så installerar Next.js det som behövs. Med allowJs inställt på true fortsätter dina befintliga .js -filer att fungera medan du konverterar filer till .tsx en i taget.

Gör TypeScript att Next.js-byggen går långsammare?

Typkontroll tar tid vid bygget, men Next.js utför ingen typkontroll i utvecklingsserverns hot reload-process, så det dagliga utvecklingsarbetet påverkas inte. I stora kodbaser kan du flytta kontrollen till ett separat CI-steg med tsc --noEmit och hålla själva bygget snabbt.

Behöver jag TypeScript för en liten Next.js-webbplats?

Förmodligen inte. En landningssida eller en tillfällig kampanjsida lever sällan tillräckligt länge för att motivera tiden det tar att sätta upp och kommentera koden. Gränsen går vid om kodbasen kommer att lämnas över till någon som inte själv har skrivit den.

Vad är skillnaden mellan getStaticProps och getServerSideProps?

getStaticProps körs vid byggtiden och genererar HTML en gång, vilket passar innehåll som sällan ändras. getServerSideProps körs vid varje anrop, vilket passar innehåll som är personligt eller ändras konstant. Båda har fullt stöd för typer i TypeScript. I App Router ersätts båda av cache-alternativ för fetch.

Bör jag använda App Router eller Pages Router med TypeScript?

Använd App Router för allt nytt, eftersom det är standard och den riktning ramverket tar. Behåll en befintlig Pages Router-kodbas där den är om du inte har en specifik anledning att flytta den: båda stöds, och de kan samexistera i samma projekt under en migrering.

blå pil till vänster
Imaginary Cloud-logotyp

Att använda ramverket Next.js och TypeScript

Startkostnaden är en tsconfig.json -fil och disciplinen att typsäkra dina props. Avkastningen kommer vid den tredje refaktoreringen, när den första nya medarbetaren börjar, och vid den första API-ändringen som annars hade skickats ut trasig.

Så gör ett hållbarhetstest på ditt eget projekt innan du bestämmer dig. Om svaren pekar på en kodbas som någon annan ska underhålla, betalar sig investeringen. Om de pekar på en prototyp, spara dig själv besväret och pennan.

Om du överväger detta för en produkt som ditt team ska leva med, diskuterar vi gärna saken med dig. Vi bygger webbprodukter med den här stacken – från Geo Matrix Decision Engine för Aurora Analytica, en Next.js-plattform som låter kliniska forskarteam köra scenarier för studiedesign på sin egen data, till AppTweaks instrumentpanel, där en ombyggnad i React och TypeScript kapade laddningstiden med 80 %. Vi ger dig ett rakt svar på om kombinationen passar ert projekt.

blå pil till vänster
Imaginary Cloud-logotyp
Anjali Ariscrisnã
Anjali Ariscrisnã

Mångsidig och datadriven tillväxtmarknadsförare med fördjupad affärskunskap, uppdaterad med den senaste utvecklingen inom det digitala marknadsföringslandskapet.

Läs fler inlägg av denna författare
Admilson Cruz
Admilson Cruz

En ung och passionerad utvecklare som är på jakt efter att göra skillnad i hur människor gör sitt dagliga liv.

Läs fler inlägg av denna författare

People who read this post, also found these interesting:

Dropdown caret icon