localStorage란? 새로고침해도 할 일 목록이 남는 이유

AI에게 “간단한 할 일 목록 웹앱을 만들어 줘”라고 요청했다고 생각해 보세요. AI가 코드를 작성해 줬고 화면에는 할 일 추가 버튼도 나타났습니다. 오늘 할 일로 “책 20쪽 읽기”를 입력하고, 나중에 브라우저를 새로고침했습니다. 그런데 두 가지 결과가 나올 수 있습니다. 첫 번째: 작성한 할 일이 모두 사라집니다. 두 번째: “책 20쪽 읽기”가 그대로 남아 있습니다. 두 번째를 구현하는 방법 가운데 하나가 오늘의 용어인 localStorage(로컬 스토리지)입니다. localStorage는 웹사이트가 방문자의 브라우저에 작은 데이터를 저장하고, 페이지를 새로고침하거나 브라우저를 닫았다 다시 열어도 같은 사이트에서 그 값을 다시 읽을 수 있도록 하는 웹 브라우저 저장 기능입니다. 하지만 localStorage가 자동으로 모든 데이터를 보존하는 마법은 아닙니다. 저장할 코드를 작성해야 하고, 저장한 브라우저·사이트·보안 조건에 영향을 받습니다. 이 글에서는 정의부터 직접 따라 해 볼 수 있는 작은 JavaScript 예제, 데이터가 저장되는 위치, 자주 발생하는 오류와 개인정보 위험까지 설명합니다. 공식 표준·개발자 문서를 참고한 설명이며, 예제 코드는 실제 사용자 사이트에서 실행해 검증한 결과가 아닙니다.

localStorage란 · 핵심 흐름localStorage란의 주요 개념과 확인 순서를 네 단계로 정리한 자체 제작 도식.localStorage란 · 핵심 흐름1localStorage 는 어디에 있는 저…localStorage 의 이름을 둘로 나누면 이해하기 쉽습니다.2새로고침하면 왜 데이터 가 사라지기도 할까…일반 웹페이지의 입력창 에 글자를 적으면 그 문자가 현재 화면의…3localStorage 는 서버나 클라우드…아닙니다. localS torage는 기본적으 로 브라우저 측…4localStorage 에 데이터를 넣는…JavaScript에서 는…설명용 요약 도식입니다. 제품의 현재 기능·조건은 본문과 공식 문서를 확인하세요.EMFLS AI · 자체 도식
자체 제작 개념도 · EMFLS AI

1. localStorage는 어디에 있는 저장 공간인가요?

localStorage의 이름을 둘로 나누면 이해하기 쉽습니다. local: 여기서는 사용자의 브라우저 환경을 뜻합니다. Storage: 정보를 저장하는 공간입니다. 예를 들어 카페에 비치된 메모지가 아니라 내가 갖고 있는 작은 수첩에 적어 두는 모습과 비슷합니다. 인터넷 연결을 끊었다고 종이에 적힌 메모가 바로 사라지는 것은 아니죠. 웹페이지에서 localStorage를 사용하면 다음처럼 작은 데이터를 기억하도록 만들 수 있습니다.

  • 사용자가 고른 다크 모드 설정
  • 마지막으로 열어 둔 메뉴의 이름
  • 일시적인 메모나 할 일 목록
  • 다른 페이지에서도 유지할 간단한 화면 설정 여기서 중요한 점은 웹사이트가 값을 저장하도록 실제로 코드를 작성했을 때만 이러한 동작이 나타난다는 것입니다. 그냥 HTML로 버튼과 입력창을 만들었다는 이유만으로 브라우저가 내용을 알아서 보관하는 것은 아닙니다.

2. 새로고침하면 왜 데이터가 사라지기도 할까요?

일반 웹페이지의 입력창에 글자를 적으면 그 문자가 현재 화면의 상태로 존재할 수 있습니다. 그런데 새로고침은 페이지를 다시 불러오는 과정입니다. 앱이 화면의 임시 값만 가지고 있다면 그 값은 새 페이지에 자동 복원되지 않습니다. 여기에 localStorage를 연결하면 이야기가 달라집니다. ① 사용자가 입력 → ② JavaScript가 localStorage에 기록 → ③ 새로고침 → ④ JavaScript가 저장한 값을 읽음 → ⑤ 화면에 다시 표시 이 흐름이 핵심입니다. 즉 localStorage는 “새로고침해도 무조건 내용이 남는 버튼”이 아니라 자바스크립트 코드가 데이터를 보관하고 복원할 수 있게 해 주는 기능입니다.

3. localStorage는 서버나 클라우드인가요?

아닙니다. localStorage는 기본적으로 브라우저 측 저장소입니다. 예를 들어 내가 노트북 Chrome에서 오늘 할 일을 저장하고 휴대전화 Chrome에서 같은 사이트에 접속했다고 가정해 볼까요? 휴대전화에서 그 목록이 자동으로 똑같이 나타나는 것은 아닙니다. localStorage는 일반적으로 저장했던 브라우저 프로필과 출처(origin)에 묶여 있습니다. 다른 기기와 자동으로 동기화되는 서버 데이터베이스와는 다릅니다. 계정에 로그인해 기기마다 같은 메모를 보여 주려면 서버·클라우드 저장소·계정 동기화 같은 추가 기능을 개발해야 합니다. 정리하면 이렇습니다.

질문 localStorage의 기본 동작
새로고침 후 값을 읽을 수 있나요? 대체로 가능
브라우저를 닫아도 남나요? 일반 모드에서는 지속될 수 있음
다른 브라우저에서 자동으로 보이나요? 아니요
다른 기기로 자동 동기화되나요? 아니요
서버에 자동 업로드되나요? 아니요
브라우저 저장 공간을 삭제하면 남나요? 삭제될 수 있음

대체로 가능이라고 표현한 이유는 개인정보 모드, 브라우저 설정, 저장 공간 제한, 사용자의 데이터 삭제 등에 따라 동작이 달라질 수 있기 때문입니다.

4. localStorage에 데이터를 넣는 기본 명령

JavaScript에서는 localStorage.setItem()을 이용해 정보를 저장할 수 있습니다. 가장 간단한 예제는 다음과 같습니다.

localStorage.setItem("todayTask", "책 20쪽 읽기");

쉽게 읽으면 todayTask라는 이름표에 “책 20쪽 읽기”를 보관해 줘라는 뜻입니다. 괄호 안에는 두 가지가 있습니다. 첫 번째 "todayTask": 데이터를 구분하는 이름입니다. 영어로는 키(key)라고 부릅니다. 두 번째 "책 20쪽 읽기": 실제로 저장할 값(value)입니다. 마치 작은 서랍에 ‘오늘 할 일’이라는 라벨을 붙이고 그 안에 쪽지를 넣는 모습과 비슷합니다. 여기서 setItem은 JavaScript 함수의 이름입니다. 이 글에서는 localStorage에서 값을 저장하는 용도로만 이해해도 충분합니다.

5. 저장한 데이터를 다시 읽는 명령

이번에는 localStorage.getItem()을 사용합니다.

const savedTask = localStorage.getItem("todayTask");
console.log(savedTask);

앞서 저장했던 이름표를 사용해 값을 불러오는 코드입니다. 개발자 도구의 Console에 다음과 같은 결과가 나타날 수 있습니다.

책 20쪽 읽기

만약 해당 이름으로 저장된 값이 없다면 getItem()은 null을 반환합니다. 아래처럼 값이 없을 때 보여 줄 문장을 준비할 수 있습니다.

const savedTask = localStorage.getItem("todayTask");
const text = savedTask ?? "아직 저장한 할 일이 없습니다.";
console.log(text);

이 예제는 todayTask 항목이 없거나 값이 null이면 대체 문장을 보여 줍니다. 핵심: 웹페이지가 데이터를 저장했다고 해서 화면에 저절로 다시 나타나지는 않습니다. 저장한 값을 읽어 화면에 표시하는 코드를 따로 작성해야 합니다.

6. 직접 만들어 보는 작은 할 일 입력창

이제 초보자용 미니 예제를 하나 살펴보겠습니다. 아래 코드는 할 일 하나를 저장하는 학습용 예시입니다. 여러 할 일을 관리하는 완성형 서비스가 아니며, 안전한 서버 동기화나 사용자 계정 기능을 포함하지 않습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>오늘 할 일</title>
</head>
<body>
  <h1>오늘 할 일</h1>
  <label for="task">할 일</label>
  <input id="task" type="text">
  <button id="save" type="button">저장</button>
  <p id="message" role="status"></p>

  <script>
    const input = document.getElementById("task");
    const message = document.getElementById("message");

    try {
      input.value = localStorage.getItem("todayTask") ?? "";
    } catch (error) {
      message.textContent = "저장된 내용을 읽을 수 없습니다.";
    }

    document.getElementById("save").addEventListener("click", () => {
      try {
        localStorage.setItem("todayTask", input.value);
        message.textContent = "현재 브라우저에 저장했습니다.";
      } catch (error) {
        message.textContent = "저장 공간 사용이 제한되었습니다.";
      }
    });
  </script>
</body>
</html>

실습을 하려면 index.html 같은 HTML 파일로 만들 수 있습니다. 다만 파일을 직접 더블클릭해서 여는 file: 방식에서는 localStorage의 동작이 브라우저에 따라 달라질 수 있습니다. 정상적인 실습 환경을 마련하려면 http://localhost 같은 로컬 개발 서버에서 페이지를 열어 확인하는 것이 안전합니다. 예제의 역할을 문장으로 풀어 보겠습니다. input: 사용자가 오늘 할 일을 적는 칸입니다. localStorage.getItem: 같은 출처에서 이전에 저장한 글자가 있으면 다시 읽습니다. localStorage.setItem: 저장 버튼을 누르면 글자를 저장합니다. try / catch: 브라우저가 저장을 막거나 오류를 반환했을 때 화면에 안내를 보여 줍니다. textContent: 안내 문장을 화면에 보여 줍니다. 예제는 사용자의 입력을 HTML로 해석해 삽입하지 않습니다. 이 코드는 교육용이며 특정 브라우저나 Blogger 게시물 안에서 실제로 실행한 결과를 기록한 것은 아닙니다. 실행 전 자신의 환경에서 저장·새로고침·오류 표시를 확인하세요.

7. 저장한 내용은 어떻게 삭제하나요?

한 항목만 지우려면 removeItem()을 사용합니다.

localStorage.removeItem("todayTask");

이는 todayTask라는 이름표가 붙은 값 하나만 제거하는 코드입니다. 한편 clear()도 있습니다.

localStorage.clear();

주의: clear()는 해당 출처의 localStorage에 들어 있는 다른 키까지 모두 삭제합니다. 내 웹앱이 아닌 다른 기능에서 사용하는 설정도 지워질 수 있습니다. 초보자가 만들고 있는 한 가지 기능의 저장값만 지우고 싶다면 removeItem("todayTask")처럼 지우려는 이름을 명확히 지정하는 편이 안전합니다.

8. localStorage는 문자열을 저장합니다

중요한 기술적 사실이 하나 있습니다. localStorage의 키와 값은 문자열(string)로 보관됩니다. 다음처럼 숫자를 저장해도 저장된 상태에서는 문자열로 읽힙니다.

localStorage.setItem("count", 3);
const result = localStorage.getItem("count");

console.log(result);        // "3"
console.log(typeof result); // "string"

리스트와 같은 복잡한 값을 저장할 때는 일반적으로 JSON 변환을 사용합니다.

const tasks = ["책 읽기", "산책하기"];

localStorage.setItem("tasks", JSON.stringify(tasks));

읽을 때는 문자열을 다시 변환할 수 있습니다.

const raw = localStorage.getItem("tasks");

let tasks = [];
try {
  tasks = raw ? JSON.parse(raw) : [];
  if (!Array.isArray(tasks)) tasks = [];
} catch (error) {
  tasks = [];
}

console.log(tasks);

JSON은 여러 데이터를 일정한 문법으로 표현한 텍스트 형식입니다. 지금은 배열을 문자열로 변환해 보관하고 다시 원래 모양으로 읽는 것이라고 이해하면 됩니다. 주의: 저장된 문자열이 올바른 JSON이 아니면 JSON.parse 과정에서 오류가 날 수 있습니다. 그래서 예제처럼 예외 처리가 필요합니다.

9. 같은 사이트인데도 저장값이 보이지 않는 이유

localStorage의 저장 범위를 이해하려면 출처(origin)를 알아야 합니다. 간단히 말해 웹사이트의 프로토콜(https 등), 호스트 이름, 포트의 조합으로 나누어집니다. 예를 들어 다음 세 주소는 서로 다른 출처일 수 있습니다.

  • https://example.com
  • http://example.com
  • https://example.com:8443 앞의 둘은 http와 https가 다르므로 다른 localStorage 영역을 사용합니다. 세 번째는 포트가 다르므로 분리됩니다. 또 https://blog.example.com과 https://example.com처럼 호스트가 달라도 일반적으로 서로 다른 출처입니다. 같은 기기에서 데이터를 저장했는데 찾지 못하는 이유가 서로 다른 주소로 앱을 열었기 때문일 수도 있습니다. 따라서 AI가 만든 웹앱이 “localhost에서는 목록이 남는데 배포한 사이트에선 비어 있다”고 해서 반드시 코드 오류인 것은 아닙니다. 주소가 달라지면 출처도 달라져 이전 localStorage를 그대로 공유하지 않기 때문입니다.

10. localStorage와 sessionStorage의 차이

이름이 비슷한 sessionStorage도 있습니다. 둘은 같은 Web Storage API의 일부이지만 보존 범위가 다릅니다.

구분 localStorage sessionStorage
기본 보존 범위 같은 출처에서 브라우저 세션을 넘어 보존될 수 있음 일반적으로 해당 탭의 페이지 세션에 한정
새로고침 값 보존 가능 값 보존 가능
탭 종료 일반 저장 모드에서는 보존될 수 있음 페이지 세션 종료 시 보통 삭제
사용 예 간단한 테마 설정, 임시 목록 탭별 일시적 입력 상태
계정별 서버 동기화 자동으로 제공하지 않음 자동으로 제공하지 않음

핵심은 'localStorage는 무한히 저장되는 영구 데이터베이스'가 아니라는 것입니다. 사용자가 사이트 데이터를 지우거나, 시크릿 모드가 끝나거나, 브라우저 환경이 달라지면 값이 사라질 수 있습니다.

11. 시크릿 모드와 저장 공간 제한도 알아두세요

시크릿 모드 또는 개인정보 보호 브라우징에서는 localStorage가 일반 창과 다른 임시 저장 공간으로 작동하고, 해당 비공개 세션이 종료되면 보통 삭제됩니다. 브라우저가 사이트 데이터 저장을 막거나 저장 용량을 초과했을 때는 예외가 발생할 수도 있습니다. 표준 API는 다음과 같은 오류 가능성을 명시합니다. SecurityError: 해당 페이지가 저장 영역에 접근할 수 없거나 보안 정책상 차단된 경우. QuotaExceededError: 저장 용량을 초과하거나 새 값을 더 이상 저장하지 못하는 경우. 예를 들어 사용자가 브라우저에서 사이트 데이터 저장을 제한했는데 저장 코드가 예외를 전혀 처리하지 않으면 버튼을 눌러도 예상대로 저장되지 않을 수 있습니다. 따라서 실제 앱에서는 try...catch와 함께 “저장되지 않았습니다”라는 메시지, 중요한 데이터의 별도 백업·동기화 방법을 고려하세요. 또 localStorage는 작은 브라우저 데이터용으로 사용하는 편이 좋습니다. 사진·대용량 파일·장기간 수정해야 하는 중요한 데이터 전체를 넣기 위한 범용 서버 저장소는 아닙니다.

12. 로그인 비밀번호와 API 키를 넣어도 되나요?

권장하지 않습니다. localStorage는 비밀정보를 안전하게 보관하기 위한 별도 보안 금고가 아닙니다. 해당 사이트의 출처에서 실행되는 JavaScript가 localStorage에 접근할 수 있습니다. 사이트에 크로스 사이트 스크립팅(XSS)과 같은 취약점이 생기면 공격자가 실행한 스크립트가 저장된 민감정보를 읽을 위험도 있습니다. 또 브라우저를 사용하는 사람이나 공유 기기의 다음 사용자가 개발자 도구에서 저장값을 확인할 수 있는 상황도 고려해야 합니다. 그러므로 다음 정보를 localStorage에 저장하는 설계는 특히 조심해야 합니다.

  • 계정 비밀번호
  • 개인 API 비밀키
  • 주민등록번호와 같은 고유식별정보
  • 고객 연락처·의료 기록 같은 민감 데이터
  • 장기간 유효한 인증 토큰 예를 들어 '비밀번호를 localStorage에 넣고 로그인 확인' 방식은 안전한 인증 방식이 아닙니다. 웹앱 로그인은 서버 측 인증, 적절한 세션 설계, HttpOnly·Secure 같은 속성이 필요한 쿠키 전략 등 별도의 보안 설계를 검토해야 합니다. 반대로 테마 색상이나 익명으로 저장해도 되는 단순 화면 설정처럼 노출되어도 큰 피해가 없는 정보는 적합한 후보가 될 수 있습니다.

13. 브라우저 개발자 도구에서 저장값을 확인하기

Chrome 계열 브라우저에서 일반적인 방법은 다음과 같습니다. 1단계: 자신의 실습용 웹앱을 엽니다. 2단계: 브라우저 개발자 도구를 엽니다. 데스크톱 Chrome에서는 F12 또는 Ctrl+Shift+I(Windows), Command+Option+I(Mac) 등으로 열 수 있습니다. 3단계: Application(애플리케이션) 탭에서 Storage → Local Storage 항목을 찾습니다. DevTools 구성은 브라우저/버전에 따라 달라질 수 있습니다. 4단계: 실습 중인 사이트의 출처를 선택합니다. 5단계: todayTask 같은 키와 저장된 값을 확인합니다. 이것은 자신이 관리하거나 실습용으로 만든 사이트의 저장 데이터를 확인하는 절차입니다. 개발자 도구에서 저장값을 수정·삭제하면 웹앱의 정상 동작에도 영향을 줄 수 있으므로 백업·테스트 범위를 정하고 진행하세요. 브라우저에서 '인터넷 사용 기록/사이트 데이터 삭제'를 실행하면 웹사이트의 저장값도 사라질 수 있습니다.

14. AI에게 웹앱을 부탁할 때 이렇게 요청해 보세요

AI가 할 일 앱을 만들었다고 해도 어디에 데이터를 저장하는지 설명하지 않았다면 다음과 같이 물어보는 것이 좋습니다.

초보자용 할 일 웹앱에서 localStorage 하나만 설명해 줘.

내가 원하는 기능:
- 사용자가 입력한 할 일 목록을 localStorage에 보관한다.
- 새로고침 뒤에도 같은 브라우저와 출처에서 목록을 불러온다.
- 항목 삭제 시 해당 저장값도 업데이트한다.
- 저장이 차단되거나 용량을 초과하면 오류 메시지를 보여 준다.
- 비밀번호·API 키·개인정보는 저장하지 않는다.
- 빈 목록과 손상된 JSON도 오류 없이 처리하도록 설계한다.

코드를 만든 다음에는
1) 저장되는 키 이름,
2) 언제 저장하고 언제 복원하는지,
3) 새로고침 테스트 방법,
4) 시크릿 모드·기기 변경에서의 제약,
5) 코드 실행·테스트를 실제 수행했는지
각 항목을 구분해서 알려 줘.

내가 실행하지 않은 테스트는 통과했다고 말하지 마.

이 프롬프트는 AI에게 구현 조건을 정확하게 전달하는 예시입니다. 모든 AI가 파일을 실행하거나 브라우저를 조작할 권한이 있는 것은 아닙니다. 작업 결과에서 코드를 작성했다는 사실과 실제로 실행해 검증했다는 사실을 구분하세요.

15. localStorage 사용 전에 체크할 다섯 가지

첫째, 데이터가 정말 작고 비밀이 아닌가요? 로컬 저장이 필요한 가벼운 화면 설정이라면 적합할 수 있습니다. 민감정보나 대용량 이미지라면 다른 설계를 검토하세요. 둘째, 여러 기기에서 공유할 필요가 있나요? 계정 로그인 뒤 다른 기기에서도 동일한 목록을 보려면 서버 데이터베이스나 동기화 기능이 필요할 수 있습니다. 셋째, 저장 실패를 처리했나요? 브라우저 정책·시크릿 모드·용량 제한 등에 대비해야 합니다. 넷째, 데이터를 삭제할 방법을 제공하나요? 사용자에게 내 데이터 삭제·초기화 방법을 알려 주고, 실수로 모든 항목을 한꺼번에 삭제하지 않도록 주의하세요. 다섯째, 실제 주소에서 새로고침 테스트를 했나요? file:로 연 임시 파일과 http://localhost, 실제 배포 주소는 동작과 저장 영역이 다를 수 있습니다. 정상 서버·브라우저 환경에서 저장·복원·삭제까지 확인하세요.

자주 묻는 질문

Q1. localStorage란 정확히 무엇인가요?

웹사이트가 방문자의 브라우저에 작은 데이터를 저장하고 이후 다시 읽도록 돕는 Web Storage API의 한 기능입니다.

Q2. 새로고침해도 정말 남나요?

정상적으로 저장했고 같은 출처·브라우저에서 다시 읽는 코드를 작성했다면 남을 수 있습니다. 단 브라우저 정책이나 데이터 삭제 등에 영향을 받습니다.

Q3. 브라우저를 완전히 닫아도 남나요?

일반 저장 모드에서는 남을 수 있지만, 시크릿 모드는 해당 비공개 세션이 종료되면 대개 삭제됩니다.

Q4. 휴대전화에서도 자동으로 같은 목록을 볼 수 있나요?

아닙니다. localStorage는 다른 기기로 자동 동기화되지 않습니다. 별도 서버 동기화 기능이 필요합니다.

Q5. 데이터를 저장하려면 어떤 명령을 쓰나요?

localStorage.setItem("키", "값")을 사용합니다.

Q6. 저장한 값을 불러오는 명령은 무엇인가요?

localStorage.getItem("키")입니다. 해당 키가 없으면 null을 반환합니다.

Q7. 한 항목만 삭제하고 싶어요.

localStorage.removeItem("키")를 사용하세요. clear()는 같은 저장 영역의 모든 항목을 지울 수 있습니다.

Q8. 숫자와 목록도 저장할 수 있나요?

값은 문자열로 저장됩니다. 목록·객체는 일반적으로 JSON.stringify로 변환해 저장하고 JSON.parse로 복원합니다.

Q9. 사이트 주소를 http에서 https로 바꾸면 어떻게 되나요?

일반적으로 서로 다른 출처로 취급돼 기존 localStorage가 자동으로 공유되지 않습니다.

Q10. localStorage에 비밀번호나 API 키를 넣어도 되나요?

권장하지 않습니다. 사이트 스크립트에서 접근할 수 있어 XSS 같은 공격에 노출될 위험이 있습니다.

Q11. 브라우저에서 사이트 데이터를 삭제하면 목록이 사라질 수 있나요?

네. localStorage는 영구 보존을 보장하는 서버 백업 저장소가 아닙니다.

Q12. 할 일 웹앱에는 localStorage만 있으면 되나요?

단일 브라우저에서 쓰는 간단한 학습용 앱에는 적합할 수 있습니다. 사용자 계정·여러 기기 동기화·민감정보·공동 편집 기능이 필요하면 추가 설계가 필요합니다.

마무리

localStorage의 핵심은 어렵지 않습니다. “웹사이트가 브라우저에 작은 정보를 저장했다가, 나중에 다시 꺼내 쓴다.” 이 한 문장만 기억하면 할 일 목록이나 테마 설정을 만드는 AI 코드의 원리가 조금 더 선명해집니다. 하지만 브라우저를 닫아도 보존될 수 있다는 장점은 자동 백업·다른 기기 동기화·비밀정보 암호화를 뜻하지 않습니다. AI에게 웹앱을 맡기더라도 무엇을 저장하고, 누구에게 보이며, 언제 사라질 수 있는지 확인하는 습관이 중요합니다.

함께 읽으면 좋은 글