리액트 앱 시작 index.html

index.html

/* 기존 디폴트로 생성된 public,src 폴더에 내용은 다 삭제 하고 깔끔한 상태에서 시작한다. */
먼저 앱을 최초 진입점 index.html 파일을 작성한다.

아래는 index.html 내용이다.

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="theme-color" content="#171717" />
    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
    <meta name="description" content="AiChat - An open source chat application with support for multiple AI models" />
    <title>AiChat</title>
    <link rel="shortcut icon" href="#" />
    <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png" />
    <link rel="apple-touch-icon" href="/assets/apple-touch-icon-180x180.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }
    </style>
    <script>
      const theme = localStorage.getItem('color-theme');
      const loadingContainerStyle = document.createElement('style');
      let backgroundColor;

      if (theme === 'dark') {
        backgroundColor = '#0d0d0d';
      } else if (theme === 'light') {
        backgroundColor = '#ffffff';
      } else if (theme === 'system') {
        const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
        backgroundColor = prefersDarkScheme ? '#0d0d0d' : '#ffffff';
      } else {
        backgroundColor = '#ffffff';
      }

      loadingContainerStyle.innerHTML = `
        #loading-container {
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100vh;
          background-color: ${backgroundColor};
        }
      `;
      document.head.appendChild(loadingContainerStyle);
    </script>
    <script defer type="module" src="/src/main.jsx"></script>
  </head>
  <body>
    <div id="root">
      <div id="loading-container"></div>
    </div>
  </body>
</html>


index.html 파일은 AiChat이라는 오픈 소스 채팅 애플리케이션의 기본 구조를 정의합니다.
 주요 기능과 구성 요소를 자세히 설명해 드릴게요.

HTML 문서 기본 구조

  • <!DOCTYPE html>: 이 문서는 HTML5 표준을 따릅니다.
  • <html lang="en-US">: 문서의 언어가 미국 영어임을 나타냅니다.

<head> 섹션: 문서 메타데이터 및 리소스

웹페이지 자체는 아니지만, 브라우저가 페이지를 렌더링하고 동작시키는 데 필요한 정보를 담고 있습니다.

메타 태그 (<meta>)

  • <meta charset="utf-8" />: 문서의 문자 인코딩을 UTF-8로 지정하여 다양한 언어의 문자가 올바르게 표시되도록 합니다.
  • <meta name="theme-color" content="#171717" />: 모바일 브라우저의 주소 표시줄이나 탭 바 같은 UI 요소의 색상을 설정합니다. 여기서는 어두운 회색으로 설정되어 있습니다.
  • <meta name="mobile-web-app-capable" content="yes" />: 안드로이드 크롬 등에서 웹 앱을 홈 화면에 추가할 때 앱처럼 실행되도록 합니다.
  • <meta name="apple-mobile-web-app-capable" content="yes" />: iOS 사파리에서 웹 앱을 홈 화면에 추가할 때 앱처럼 실행되도록 합니다.
  • <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />: iOS 웹 앱에서 상단 상태바의 스타일을 투명한 검정색으로 설정합니다.
  • <meta name="description" content="AiChat - An open source chat application with support for multiple AI models" />: 웹페이지에 대한 간략한 설명을 제공합니다. 검색 엔진 최적화(SEO)에 사용될 수 있습니다.
  • <meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />: 뷰포트 설정을 정의합니다.
    • width=device-width: 뷰포트의 너비를 장치 너비에 맞춥니다.
    • initial-scale=1: 초기 확대/축소 수준을 1배로 설정합니다.
    • interactive-widget=resizes-content: 가상 키보드 등 대화형 위젯이 나타날 때 콘텐츠가 재배치되도록 지시합니다.

제목 (<title>)

  • <title>AiChat</title>: 웹페이지의 제목을 설정합니다. 브라우저 탭이나 즐겨찾기 목록에 표시됩니다.

파비콘 및 아이콘 (<link>)

  • <link rel="shortcut icon" href="#" />: 오래된 브라우저를 위한 파비콘 설정입니다. 현재는 비어있습니다.
  • <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png" />: 32x32 픽셀 크기의 PNG 파비콘을 지정합니다.
  • <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png" />: 16x16 픽셀 크기의 PNG 파비콘을 지정합니다.
  • <link rel="apple-touch-icon" href="/assets/apple-touch-icon-180x180.png" />: iOS 기기에서 홈 화면에 추가할 때 사용되는 아이콘을 지정합니다.

인라인 스타일 (<style>)

  • html, body { margin: 0; padding: 0; height: 100%; }: htmlbody 요소의 기본 여백과 패딩을 제거하고 높이를 100%로 설정하여 전체 화면을 차지하게 합니다.

인라인 스크립트 (<script>) - 로딩 화면 처리

<script> 블록은 페이지가 로드되기 전에 로딩 화면의 배경색을 설정하는 역할을 합니다.

  1. 테마 감지: localStorage.getItem('color-theme')를 통해 사용자가 이전에 선택한 테마(dark, light, system)를 가져옵니다.
  2. 배경색 결정:
    • 테마가 'dark'이면 배경색을 #0d0d0d (아주 어두운 회색)로 설정합니다.
    • 테마가 'light'이면 배경색을 #ffffff (흰색)으로 설정합니다.
    • 테마가 'system'이면 사용자의 시스템 설정(window.matchMedia('(prefers-color-scheme: dark)'))을 확인하여 어두운 모드이면 #0d0d0d, 아니면 #ffffff로 설정합니다.
    • 테마가 설정되지 않았거나 인식할 수 없으면 기본값으로 #ffffff를 사용합니다.
  3. 동적 스타일 삽입: loadingContainerStyle이라는 <style> 요소를 생성하고, 위에서 결정된 backgroundColor를 사용하여 #loading-container ID를 가진 요소의 스타일을 동적으로 정의합니다. 이 스타일은 로딩 화면을 중앙에 배치하고 결정된 배경색을 적용합니다.
  4. document.head.appendChild(loadingContainerStyle);: 생성된 스타일 요소를 <head> 섹션에 추가하여 즉시 적용되도록 합니다.

외부 스크립트 (<script defer type="module" src="/src/main.jsx"></script>)

  • defer: 이 스크립트가 HTML 파싱이 완료된 후에 실행되도록 지연시킵니다.
  • type="module": 이 스크립트가 ES 모듈임을 나타냅니다.
  • src="/src/main.jsx": 애플리케이션의 메인 JavaScript/JSX 파일입니다. 실제 AiChat 애플리케이션의 로직과 UI가 이 파일에서 시작됩니다.

<body> 섹션: 문서 콘텐츠

웹페이지에 실제로 표시되는 내용을 담고 있습니다.

  • <div id="root">: 애플리케이션의 루트 요소입니다. 일반적으로 React, Vue, Angular 등과 같은 프런트엔드 프레임워크가 이 div 안에 모든 UI를 렌더링합니다.
  • <div id="loading-container"></div>: 앱이 완전히 로드되기 전에 사용자에게 표시되는 로딩 화면입니다. 위 <script> 블록에서 이 요소의 배경색이 동적으로 설정됩니다. 애플리케이션이 완전히 로드되면 main.jsx 파일에서 이 로딩 컨테이너를 숨기거나 제거할 것으로 예상됩니다.

요약

index.html 파일은 AiChat 애플리케이션의 진입점 역할을 합니다. 페이지 로드 시 사용자 시스템의 테마 설정을 기반으로 로딩 화면의 배경색을 동적으로 설정하여 시각적인 일관성을 제공합니다. 그리고 <div id="root">를 통해 메인 애플리케이션 (main.jsx)을 로드하여 실제 채팅 인터페이스를 렌더링하는 준비를 합니다. 전반적으로 사용자 경험을 고려하여 로딩 과정을 부드럽게 처리하려는 의도가 엿보입니다.


댓글

이 블로그의 인기 게시물

아파치 보안관련 기본설정

티베로 이관 작업 절차

윈도우 네트워크 리소스 사용권한 오류