SvelteKit에서 Local Storage 사용하기(localStorage is not defined error)

!0!·2024년 3월 13일
0

기본적인 로컬 스토리지 사용법의 비중이 더 많지만.. 그 부분은 더 자세하게 설명된 블로그 글이 많을 것 같아 'SvelteKit에서 Local Storage 사용하기'로 제목을 지었습니다. 스벨트킷 관련 내용만 보고 싶으신 분들은 오른쪽 목차의 'SvelteKit에서 Local Storage 사용하기'로 빠르게 ㄱㄱ!

Local Storage란?

웹 스토리지 객체의 한 종류로, browser에 key-value 쌍을 반영구적으로 저장. 브라우저를 닫아도 유지되며(↔ 세션스토리지) 삭제하기 전까지 남아있음

SvelteKit에서 Local Storage 사용하기

  • svelteKit은 SSR과 CSR을 모두 지원하지만, client-side 렌더를 하기전에 server-side 렌더를 먼저 수행하기 때문에 localStorage is not defined error가 날 수 있음
  • event handler의 콜백함수 등에서 사용하는 것처럼 client-side에 렌더링되기까지 기다린다면 에러 발생하지 않음
  • browser에서 running되고 있는지 확인할 수 있는 browser(boolean)
    import { browser } from '$app/environment'
    
    if(browser)
        localStorage.setItem('key', JSON.stringify('value'))
    • browser은 app이 browser에서 돌아갈 때 true가 되는 boolean 값
    • browser가 true일 때만 localStorage 사용하면 에러 발생하지 않음
      • 예: browser && localStorage.getItem('user')
    • 빌드할 때 문제가 있어 권장하지 않는 것 같음
  • 관련 참고 링크: https://www.okupter.com/blog/sveltekit-window-is-not-defined

스벨트킷 별 거 아닌 검색팁! 아마 Next.js를 쓰는 분들은 이와 비슷한 에러를 많이 겪어보지 않았나 싶다. 그런데 넥스트와 달리 스벨트킷은 정보가 많이 없다. localStorage를 바로 검색하기보다는 localStorage 속성을 포함하고 있는 window 객체를 검색하면 더 많은 결과를 얻을 수 있다. 아니면 넥스트로 검색해보고 원인의 힌트를 얻는 것도 도움이 될 수도 있겠다.(지금 생각한 거라 아직 안 해봤음)

=> 결론! 로컬 스토리지를 사용하려는 곳이 모두 콜백함수 속이기 때문에(사용자가 버튼을 눌렀을 때 뜨는 내용들을 저장한다거나..) 어딘가 찜찜한 browser는 사용하지 않고, 로컬 스토리지를 사용하기로 했다.

Local Storage 객체 사용법

  • localStorage.setItem(key, value) // 쓰기
  • localStorage.getItem(key) // 읽기
  • localStorage.removeItem(key) // 특정 아이템 삭제
  • localStorage.clear() // 전체 삭제
  • localStorage.key(index) // index로 key 찾기
  • localStorage.length // 개수
    (이번 프로젝트에 필요할 것 같은 메소드들만 볼드체로 적어둠)

기타 유의사항

  • value에는 string 값만 들어감
    • 객체, 배열을 사용할 때에는 JSON.stringify()를 사용하여 넣어주기
    • 예시
      • JSON.stringify() 사용하지 않은 경우: 코드 // 콘솔

        localStorage.setItem('obj1', {obj1 : 'object1'}) // undefined
        localStorage.getItem('obj') // '[object Object]'
        localStorage.setItem('arr1', [1, 2, 3]) // undefined
        localStorage.getItem('arr1') // '1,2,3'
      • JSON.stringify() 사용한 경우: 코드 // 콘솔

        localStorage.setItem('obj2’, JSON.stringify({obj2 : 'object2'}))
        localStorage.getItem('obj2') // '{"obj1":"object"}'
        localStorage.setItem('arr2', JSON.stringify([1,2,3])) // undefined
        localStorage.getItem('arr2') // '[1,2,3]'
      • JSON.parse()를 이용해 원래의 형태(객체, 배열)로 변환: 코드 // 콘솔

        JSON.parse(localStorage.getItem('obj2')) // {obj1: 'object'}
        JSON.parse(localStorage.getItem('arr2')) // (3) [1, 2, 3]

        cf) 숫자 1을 넣으면 문자로 자동형변환되므로 getItem 결과 ! == 1

  • 일반 객체처럼 사용할 수 있지만 권장되지 않음
    • 예시: 코드 // 콘솔
      localStorage.arr // '1,2,3'
      localStorage['setKey'] = 'setValue' // 'setValue'
      localStorage.getItem('setKey') // 'setValue'
      
      delete localStorage.setKey // true
      delete localStorage.arr // true

Local Storage 용량

브라우저마다 사용 가능한 용량이 다르지만 5MB 이상.

Lorem Ipsum의 데이터로 많은 양의 글씨를 넣어본 결과, 사파리, 크롬 모두 같은 용량에서 QuotaExceededError가 발생했다.

  • 4.8MB ~ 5.2MB 에서 에러 발생
    • 100바이트 * 48201 (4.8MB)
    • 8016바이트 * 647 + a (5.2MB)

한글 데이터로 치면 250만 글자 정도 저장 가능하다고 볼 수 있다.

로컬스토리지 공유여부

  • 시크릿 모드로 들어가 봤을 때 공유하지 않음
    (로컬 스토리지니까 당연히.. 그래야겠지만.. 언제 공유된 적이 있다고 해서 테스트해보았다.)

0개의 댓글

관련 채용 정보