<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Sveltekitblog Engine</title>
        <link>https://sveltekitblogblog.pages.dev</link>
        <description>Welcome to the new blog. (Please modify this text in settings.)</description>
        <language>en</language>
        <atom:link href="https://sveltekitblogblog.pages.dev/en/rss.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Mon, 22 Jun 2026 08:37:35 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Blog and Admin Feature Integration Overview]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/general-guide/general-integration-guide</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/general-guide/general-integration-guide</guid>
            <pubDate>Sat, 20 Jun 2026 02:54:35 GMT</pubDate>
            <description><![CDATA[An integration document linking layout options, communication systems, multi-language publishing, and real-time design editors of the blog and admin console.]]></description>
            <content:encoded><![CDATA[<h1 id="blog-and-admin-feature-integration-overview">📖 Blog and Admin Feature Integration Overview</h1>
<p>This document links individual feature overview pages to provide a structured map of the blog service and administration (admin) features.</p>
<p><em>Note: Detailed connection guidelines and technical manuals for each feature will be published individually in future posts.</em></p>
<hr>
<h2 id="feature-overview-index">📂 Feature Overview Index</h2>
<ul>
<li><strong>Admin Features</strong><ul>
<li><strong><a href="../admin-guide/admin-install-and-deploy">CMD One-Click Installation and Deployment</a></strong>: An overview of deploying and restoring the blog infrastructure to Cloudflare with single CLI commands.</li>
<li><strong><a href="../admin-guide/admin-getting-started">Admin Initial Configurations and Login</a></strong>: Details on primary master password login, whitelist IP configuration, and workspace setup.</li>
<li><strong><a href="../admin-guide/admin-core-features">Core Admin Features and Dual Editors</a></strong>: Introduces Visual HTML and Markdown editors, batch-saving, and column layouts for desktop/mobile viewports.</li>
<li><strong><a href="../admin-guide/admin-design-editor">Design Editor and Background Customizations</a></strong>: Outlines background styles (solid, gradient, image, canvas scripts) and live theme updates.</li>
<li><strong><a href="../admin-guide/admin-faq">Admin Frequently Asked Questions (FAQ)</a></strong>: Verifies storage integration parameters and resolves database backup/restore errors.</li>
</ul>
</li>
<li><strong>Blog Features</strong><ul>
<li><strong><a href="../blog-guide/blog-getting-started">Blog Homepage Layout and Login</a></strong>: Highlights homepage widgets, multi-language UI switches, and login integrations.</li>
<li><strong><a href="../blog-guide/blog-core-features">Reader Communications and Multi-Language Viewers</a></strong>: Describes language-specific routing, translation fallbacks, and nested comment chains.</li>
<li><strong><a href="../blog-guide/blog-faq">Reader Frequently Asked Questions (FAQ)</a></strong>: Explains account deletion data anonymization policies and temporary activity restrictions.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="core-process-of-blog-management">🚀 Core Process of Blog Management</h2>
<p>An overview of the setup and authoring workflow for blog administrators.</p>
<h3 id="1-ip-whitelisting-and-master-login">1. IP Whitelisting and Master Login</h3>
<ul>
<li>Initially accessing the admin panel requires the user&#39;s public IP address to be whitelisted in the environment variables (<code>ALLOWED_IP</code>) to bypass security filters.</li>
<li>Enter the master password on the secure login screen to establish your session.</li>
</ul>
<h3 id="2-multi-language-batch-saving">2. Multi-Language Batch Saving</h3>
<ul>
<li>Switch between the translation tabs in the writing editor to write content, and click the save button to publish or draft all languages simultaneously to the database.</li>
</ul>
<h3 id="3-real-time-theme-updates">3. Real-Time Theme Updates</h3>
<ul>
<li>Configure styles, colors, and interactive canvas backgrounds in the design editor. Saving changes propagates parameters as CSS variables in visitors&#39; browsers instantly, without redeployment.</li>
</ul>
]]></content:encoded>
            <category>Integration Guide</category>
        </item>
        <item>
            <title><![CDATA[Reader Policy and Frequently Asked Questions (FAQ)]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/blog-guide/blog-faq</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/blog-guide/blog-faq</guid>
            <pubDate>Sat, 20 Jun 2026 02:50:33 GMT</pubDate>
            <description><![CDATA[Introduces core principles regarding user data processing upon membership withdrawal and policies for service activity restrictions.]]></description>
            <content:encoded><![CDATA[<h1 id="reader-policy-and-frequently-asked-questions-faq">❓ Reader Policy and Frequently Asked Questions (FAQ)</h1>
<p>This document introduces the basic principles of personal information and data processing upon account deletion, and the service activity restriction policy.</p>
<hr>
<h2 id="q1-what-happens-to-my-comments-and-guestbook-posts-when-i-delete-my-account">🚪 Q1. What happens to my comments and guestbook posts when I delete my account?</h2>
<p>The blog system applies an <strong>author anonymization policy</strong> to simultaneously protect the user&#39;s privacy and maintain the integrity of dialogue threads within the site.</p>
<h3 id="data-processing-principles-upon-deletion">💡 Data Processing Principles Upon Deletion</h3>
<ol>
<li><strong>Personal Identification Data Removal</strong>:<ul>
<li>When you delete your account, personal data that identifies you (such as login email, social profile image, and nickname) is immediately removed from the database.</li>
</ul>
</li>
<li><strong>Content Data Retention</strong>:<ul>
<li>Your comments and guestbook messages remain on the screen to preserve the context of past discussions and conversations.</li>
</ul>
</li>
<li><strong>Nickname Anonymization</strong>:<ul>
<li>The link between your account and your posts is severed, and the author name automatically switches to <strong>&quot;Unknown&quot;</strong>. This prevents reverse-tracking of the actual author&#39;s identity.</li>
</ul>
</li>
</ol>
<ul>
<li><em>Note: If the administrator manually deletes your membership record entirely, your comments and guestbook entries may also be removed.</em></li>
</ul>
<hr>
<h2 id="q2-my-comment-submissions-are-blocked-or-an-activity-restriction-notice-appears">🚫 Q2. My comment submissions are blocked, or an activity restriction notice appears.</h2>
<p>Checklist when your service usage is temporarily restricted (banned) due to policy violations (such as posting spam or offensive content).</p>
<h3 id="core-checklist-for-activity-restrictions">💡 Core Checklist for Activity Restrictions</h3>
<ol>
<li><strong>Feature Limitations</strong>:<ul>
<li>When an activity restriction is applied, your login state remains active, but direct interactions such as posting comments, nested replies, or guestbook entries are temporarily restricted.</li>
</ul>
</li>
<li><strong>Restriction Details</strong>:<ul>
<li>When restricted, you can view the specific reason and the expiration date of the restriction via the on-screen alert or your account profile page.</li>
</ul>
</li>
<li><strong>Activity Resumption</strong>:<ul>
<li>Once the restriction period set by the administrator expires or the restriction is lifted after policy review, you will be able to resume normal activities.</li>
</ul>
</li>
</ol>
]]></content:encoded>
            <category>User Guide</category>
        </item>
        <item>
            <title><![CDATA[Blog Core Features and Multi-Language Service Overview]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/blog-guide/blog-core-features</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/blog-guide/blog-core-features</guid>
            <pubDate>Sat, 20 Jun 2026 02:47:24 GMT</pubDate>
            <description><![CDATA[An introduction to the blog's core features including real-time multi-language rendering and manual translation fallback, comment/reply hierarchies, and private guestbook posts.]]></description>
            <content:encoded><![CDATA[<h1 id="blog-core-features-and-multi-language-service-overview">🌐 Blog Core Features and Multi-Language Service Overview</h1>
<p>This document introduces core features of the blog, including viewing multi-language post translations and communicating via comments and the guestbook.</p>
<hr>
<h2 id="1-real-time-multi-language-body-switching-i18n">🌐 1. Real-Time Multi-Language Body Switching (i18n)</h2>
<p>This blog features a real-time multi-language viewer that updates not just basic UI labels but the actual post content itself to the selected language.</p>
<h3 id="how-it-works-amp-key-features">⚙️ How It Works &amp; Key Features</h3>
<ul>
<li><strong>Language-Specific URL Routing</strong>: Clicking the globe icon at the top or the language buttons near the post title directs the browser to the language-specific URL (e.g., prefixing with <code>/en</code> or <code>/ja</code>). In addition to default languages (Korean, English, Japanese), administrators can expand and publish in other languages by configuring the translation dictionary.</li>
<li><strong>Manually Authored Data Loading (Not Machine Translation)</strong>: The system does not automatically machine-translate text in real time. Instead, it queries and loads the specific post data manually translated and saved by the author under each language tab (such as content translated using AI or translation services and stored in the database).</li>
<li><strong>Simultaneous Content &amp; Metadata Loading</strong>: More than simple text replacement, the database-stored title, excerpt, tags, and body HTML are completely swapped with the datasets of the selected language.</li>
<li><strong>Untranslated Post Fallback</strong>: If the author has not registered a translation for a specific language, the system shows a notice stating the translation is unavailable and falls back to rendering the default authoring language (e.g., Korean text) to ensure the reader&#39;s flow is uninterrupted.</li>
</ul>
<hr>
<h2 id="2-comment-and-nested-reply-hierarchy">💬 2. Comment and Nested Reply Hierarchy</h2>
<p>A clean comment section is placed below each article to facilitate discussion for both guest visitors and registered members.</p>
<ul>
<li><strong>Sharing Thoughts</strong>: Logged-in users can write and post comments to share ideas.</li>
<li><strong>Hierarchical Replies (Nested Comments)</strong>: Users can reply to a specific comment, organizing discussions in an easy-to-read tree structure.</li>
<li><strong>Security &amp; Integrity Preservation</strong>: Users can delete their own comments. However, if a comment with active replies is deleted, the system masks the content with the text &quot;This comment has been deleted&quot; to prevent breaking the overall thread hierarchy.</li>
</ul>
<hr>
<h2 id="3-guestbook-and-private-posts">📖 3. Guestbook and Private Posts</h2>
<p>Provides communication features through the blog guestbook page.</p>
<h3 id="private-guestbook-features">⚙️ Private Guestbook Features</h3>
<ul>
<li><strong>Writing Private Posts</strong>: Checking the <strong>[🔒 Private Post]</strong> checkbox hides the message from the general public.</li>
<li><strong>Exposure Restriction</strong>: Private guestbook posts are completely excluded from the lists of third-party visitors and logged-out users.</li>
<li><strong>Secure Communication</strong>: The post body is visible only to the author (when logged in) and the site administrator, ensuring private communication.</li>
</ul>
]]></content:encoded>
            <category>User Guide</category>
        </item>
        <item>
            <title><![CDATA[Blog Homepage Layout and Getting Started with Login]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/blog-guide/blog-getting-started</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/blog-guide/blog-getting-started</guid>
            <pubDate>Sat, 20 Jun 2026 02:41:11 GMT</pubDate>
            <description><![CDATA[A brief introduction to the basic homepage layout and login/registration procedures of the blog app.]]></description>
            <content:encoded><![CDATA[<h1 id="blog-homepage-layout-and-getting-started-with-login">🌐 Blog Homepage Layout and Getting Started with Login</h1>
<p>This document provides a brief overview of the blog (<code>apps/blog</code>) homepage layout and basic login/registration methods.</p>
<hr>
<h2 id="1-blog-layout-and-navigation">🎨 1. Blog Layout and Navigation</h2>
<p>The blog layout is designed to help visitors locate information efficiently (Header, Sidebar, Main Content, and Footer).</p>
<ol>
<li><strong>Navigation Header (Header)</strong>:<ul>
<li><strong>Site Logo</strong>: Click to return to the homepage at any time.</li>
<li><strong>Shortcut Menu</strong>: Lists primary links configured by the administrator (e.g., categories, external channels).</li>
<li><strong>Language Selector</strong>: Click the globe icon to switch both menu languages and post translations instantly.</li>
</ul>
</li>
<li><strong>Sidebar</strong>:<ul>
<li>Displays category lists, the author profile card, and popular tags on desktop screens.</li>
<li>Automatically hidden on mobile resolutions to optimize readability and scrolling.</li>
</ul>
</li>
<li><strong>Main Content</strong>:<ul>
<li>Shows category filters and the latest published articles in card format.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="2-registration-and-login">🔑 2. Registration and Login</h2>
<p>Supports account registration and login for writing comments or guestbook entries.</p>
<h3 id="supported-login-and-sign-up-methods">⚙️ Supported Login and Sign-Up Methods</h3>
<ul>
<li><strong>Default Email Login/Sign-Up (Default)</strong>:<ul>
<li>Enabled by default post-installation. Users can sign up by providing an email address, display name (nickname), and password. Auto-login applies immediately upon successful registration.</li>
</ul>
</li>
<li><strong>Social Login (Better-Auth)</strong>:<ul>
<li>Powered by the Better-Auth engine, supporting <strong>21 social login providers</strong> including Google, GitHub, Kakao, and Naver.</li>
<li>Social login buttons will only appear and function on the login screen after the administrator configures the respective client IDs and secrets as environment variables on the backend. (Integration details for social providers will be detailed in separate upcoming documents.)</li>
</ul>
</li>
<li><strong>Login Status Display</strong>:<ul>
<li>Upon logging in, the top-right button switches to your profile image icon and a link to my-page.</li>
<li><em>Note: The user profile photo integration is currently in progress and may display a default profile icon instead.</em></li>
</ul>
</li>
</ul>
]]></content:encoded>
            <category>User Guide</category>
        </item>
        <item>
            <title><![CDATA[Admin Frequently Asked Questions (FAQ)]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/admin-guide/admin-faq</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/admin-guide/admin-faq</guid>
            <pubDate>Sat, 20 Jun 2026 02:34:34 GMT</pubDate>
            <description><![CDATA[Check database backup/restore guidelines, external media storage settings, and dashboard analytics configuration.]]></description>
            <content:encoded><![CDATA[<h1 id="admin-frequently-asked-questions-faq">❓ Admin Frequently Asked Questions (FAQ)</h1>
<p>This document covers common questions, causes, and checklist items regarding backup/restore, external media storage integration, and dashboard statistics in the admin page.</p>
<hr>
<h2 id="q1-an-error-occurs-during-backup-data-import-restore">🗄️ Q1. An error occurs during backup data import (Restore).</h2>
<p>Checklist when an error occurs during restore after choosing a backup file.</p>
<h3 id="core-checklist">💡 Core Checklist</h3>
<ol>
<li><strong>Corrupted Backup File</strong>:<ul>
<li>If the text was not saved properly during download, restore may fail. Open the <code>.json</code> file in a text editor to verify that it has a valid data format.</li>
</ul>
</li>
<li><strong>Menu Path Mismatch</strong>:<ul>
<li>You must use the restore menu that matches your data type. Post data must be restored under the <strong><code>Data Backup &amp; Restore</code></strong> section of the <strong><code>Content Backup</code></strong> menu; image media files must be restored under the <strong><code>Media Backup &amp; Restore</code></strong> section of the <strong><code>Content Backup</code></strong> menu; and complete system data must be restored under the <strong><code>Full System Backup &amp; Restore</code></strong> section of the <strong><code>Site Settings</code></strong> menu.</li>
</ul>
</li>
<li><strong>Database (D1) Binding</strong>:<ul>
<li>Verify in the Cloudflare management console that your database (D1) connection binding is properly associated.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="q2-upload-or-display-errors-occur-after-switching-the-media-storage-provider">📂 Q2. Upload or display errors occur after switching the media storage provider.</h2>
<p>Analysis of causes when upload errors occur or images are not displayed after switching the storage provider from default KV to R2, Supabase, or ImageKit.</p>
<h3 id="core-checklist-1">💡 Core Checklist</h3>
<ol>
<li><strong>Cloudflare R2</strong>:<ul>
<li>Verify if the <code>IMAGES</code> R2 bucket binding is correctly associated in your project settings (<code>wrangler.json</code>).</li>
</ul>
</li>
<li><strong>Supabase Storage</strong>:<ul>
<li>Check the accuracy of the entered API endpoint (<code>supabase_storage_url</code>), Service Role Key (<code>supabase_storage_key</code>), and bucket name (<code>supabase_storage_bucket</code>). The bucket&#39;s access control list (ACL) must be set to <strong>Public</strong> for images to be visible externally.</li>
</ul>
</li>
<li><strong>ImageKit.io</strong>:<ul>
<li>Check the format of the entered endpoint URL (<code>imagekit_url_endpoint</code>) and inspect cross-origin resource sharing (CORS) settings.</li>
</ul>
</li>
<li><strong>Upload Size Restrictions</strong>:<ul>
<li>High-resolution images may fail to upload due to size limitations per request in the edge server environment. Shrink the original image dimensions before uploading.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="q3-dashboard-analytics-charts-display-only-demo-data">📊 Q3. Dashboard analytics charts display only demo data.</h2>
<p>Checklist when demo data is displayed instead of actual traffic metrics on the main dashboard.</p>
<h3 id="core-checklist-2">💡 Core Checklist</h3>
<ul>
<li><strong>Cause</strong>: If the Google Analytics 4 (GA4) API credentials/environment variables are missing or incorrect, placeholder demo data is rendered to prevent dashboard crashes.</li>
<li><strong>Setup Instructions</strong>: Add the following environment variables to the Cloudflare Pages settings and redeploy:<ul>
<li><code>GA4_PROPERTY_ID</code>: Google Analytics Property ID</li>
<li><code>GA4_CLIENT_EMAIL</code>: Google Cloud Service Account Email</li>
<li><code>GA4_PRIVATE_KEY</code>: Google Service Account Private Key</li>
</ul>
</li>
<li><strong>Google AdSense</strong>: If you wish to integrate the AdSense revenue dashboard, verify that the <code>ADSENSE_ACCOUNT_ID</code> environment variable is correctly set.</li>
</ul>
]]></content:encoded>
            <category>Admin Guide</category>
        </item>
        <item>
            <title><![CDATA[Real-Time Design Editor and Background Customization Overview]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/admin-guide/admin-design-editor</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/admin-guide/admin-design-editor</guid>
            <pubDate>Sat, 20 Jun 2026 02:26:20 GMT</pubDate>
            <description><![CDATA[Instant real-time theme updates without rebuilds or redeployments.]]></description>
            <content:encoded><![CDATA[<h1 id="real-time-design-editor-and-background-customization-overview">🎨 Real-Time Design Editor and Background Customization Overview</h1>
<p>This document introduces the system that applies theme configurations in real time without requiring server rebuilds or redeployments, and outlines the 4 background settings: Solid, Gradient, Background Image, and Custom JavaScript Canvas.</p>
<hr>
<h2 id="1-real-time-design-editor-overview">🌌 1. Real-Time Design Editor Overview</h2>
<p>When you modify and save configuration values in the design editor, there is no need to rebuild or redeploy the blog server or CDN services. The database updates instantly, and the <strong>CSS variables and background rendering module reflect in the visitor&#39;s browser within seconds</strong>.</p>
<h3 id="basic-theme-customization">🎨 Basic Theme Customization</h3>
<ul>
<li><strong>Core Color Settings</strong>: Modify the Primary theme color, Secondary color, body Text color, Accent highlight color, Card Background (Card Bg), and Border colors.</li>
<li><strong>Layout Specifications</strong>: Adjust sidebar margin, maximum container width, card border radius, and box shadow effects.</li>
<li><strong>Typography Settings</strong>: Apply modern typefaces by entering Google Fonts names, and easily set the base font size.</li>
</ul>
<hr>
<h2 id="2-device-specific-independent-widget-placement">🧱 2. Device-Specific Independent Widget Placement</h2>
<p>Configure widget positioning in the sidebar and content areas using drag-and-drop. You can customize layouts differently based on the visitor&#39;s screen size.</p>
<ul>
<li><strong>Desktop</strong>: Displays selected widgets (e.g., tag clouds, category trees) only on wider screens. For mobile access, elements are omitted at the HTML transmission stage to maintain fast loading times.</li>
<li><strong>Mobile</strong>: Hides the widget on desktop viewports and restricts exposure exclusively to smartphone-sized mobile resolutions.</li>
</ul>
<hr>
<h2 id="3-4-background-customization-options">🌈 3. 4 Background Customization Options</h2>
<p>Customize the sensory atmosphere of the blog using four supported background types:</p>
<h3 id="solid-solid-background">① Solid (Solid Background)</h3>
<ul>
<li>Choose a HEX code (e.g., <code>#3b82f6</code>) or HSL color code to create a clean, distraction-free screen that helps readers focus on the post content.</li>
</ul>
<h3 id="gradient-gradient-background">② Gradient (Gradient Background)</h3>
<ul>
<li>Create linear gradients where multiple colors blend smoothly using the <strong>Gradient Builder</strong> tool.</li>
<li>Adjust the gradient angle (Direction) slider and add or slide color stops to customize starting, intermediate, and ending colors.</li>
</ul>
<h3 id="image-background-image-amp-glassmorphism">③ Image (Background Image &amp; Glassmorphism)</h3>
<ul>
<li>Specify a remote image URL or use the upload button to add media assets to your library.</li>
<li><strong>Upload Optimization</strong>: Uploaded images are automatically converted to WebP format to prevent initial page load delays.</li>
<li><strong>Glassmorphism Overlay</strong>: Adjust the controls below to build a glassmorphism aesthetic that ensures text readability over background images.</li>
</ul>
<table>
<thead>
<tr>
<th align="left">Setting</th>
<th align="center">Recommended Range</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><strong>Glass Blur</strong></td>
<td align="center"><code>5px ~ 15px</code></td>
<td align="left">Applies a translucent frosted-glass blur filter below the content cards.</td>
</tr>
<tr>
<td align="left"><strong>Overlay Opacity</strong></td>
<td align="center"><code>10% ~ 30%</code></td>
<td align="left">Controls the opacity of the mask overlaid behind the card container.</td>
</tr>
<tr>
<td align="left"><strong>Overlay Color</strong></td>
<td align="center"><code>#000000</code> or <code>#ffffff</code></td>
<td align="left">Selects dark or light mask colors to maintain text contrast.</td>
</tr>
</tbody></table>
<h3 id="custom-javascript-custom-javascript-amp-canvas-background">④ Custom JavaScript (Custom JavaScript &amp; Canvas Background)</h3>
<ul>
<li>Supports custom JavaScript execution to render interactive Canvas animations on the client&#39;s browser background.</li>
<li>Provides direct rendering control over the background canvas element (<code>canvas id=&quot;bg-canvas&quot;</code>). Detailed security restrictions and power-saving policies are explained in <strong>[4. Custom JavaScript Integration Specifications]</strong> below.</li>
</ul>
<hr>
<h2 id="4-custom-javascript-integration-specifications">⚡ 4. Custom JavaScript Integration Specifications</h2>
<p>To prevent security risks and conserve mobile battery life, the following sandbox environment and battery-saving systems are applied.</p>
<h3 id="security-sandbox-and-csp">🔒 Security Sandbox and CSP</h3>
<p>The following security measures protect against malicious script injections:</p>
<ol>
<li><strong>Isolated Sandbox Structure</strong>: Canvas code runs inside an isolated <code>iframe</code> with limited execution privileges. Access to the parent page DOM, session cookies, or login credentials is blocked.</li>
<li><strong>Content Security Policy (CSP)</strong>: Outbound network calls and external script injections are completely blocked. Sensitive data cannot be leaked to external servers.</li>
<li><strong>JS API Restrictions</strong>: Disallowed APIs, including <code>fetch</code>, <code>XMLHttpRequest</code>, <code>WebSocket</code>, <code>eval</code>, <code>new Function</code>, <code>document.cookie</code>, and <code>localStorage</code>, are intercepted and commented out (<code>/* f_e_t_c_h (blocked) */</code>) by the validator script (<code>jsValidator.ts</code>).</li>
</ol>
<h3 id="power-and-performance-optimization">🔋 Power and Performance Optimization</h3>
<ul>
<li><strong>Out-of-View Auto-Pause</strong>: If a visitor scrolls and the background animation leaves the viewport, the render loop <strong>enters sleep mode</strong> to conserve CPU and GPU cycles. The animation resumes instantly when scrolled back into view.</li>
<li><strong>Mobile Frame Throttling</strong>: Background scripts are paused on mobile devices by default to prevent device overheating. Enabling the <strong>&quot;Run animation on mobile devices&quot;</strong> option scales down particle counts automatically to match mobile processing thresholds.</li>
</ul>
<hr>
<h2 id="5-sample-background-script-code-3-types">📝 5. Sample Background Script Code (3 Types)</h2>
<p>Choose <strong>[Custom JavaScript]</strong> in the background settings and copy one of the templates below into the code editor.</p>
<blockquote>
<p>[!NOTE]<br>Scripts must acquire the target canvas context using <code>document.getElementById(&#39;bg-canvas&#39;)</code>.</p>
</blockquote>
<h3 id="sample-a-winter-snowfall-snowfall">❄️ Sample A. Winter Snowfall (Snowfall)</h3>
<p>A background animation where snowflakes drift slowly down the screen.</p>
<pre><code class="language-javascript">(function() {
  const canvas = document.getElementById(&#39;bg-canvas&#39;);
  if (!canvas) return;
  const ctx = canvas.getContext(&#39;2d&#39;);
  
  let width = canvas.width = window.innerWidth;
  let height = canvas.height = window.innerHeight;
  
  // Mobile throttle detection
  const divisor = (window.bgConfig &amp;&amp; window.bgConfig.mobileThrottleDivisor) || 1;
  const maxSnowflakes = Math.floor(100 / divisor);
  const snowflakes = [];
  
  class Snowflake {
    constructor() {
      this.reset();
      this.y = Math.random() * height; // Initial random altitude
    }
    
    reset() {
      this.x = Math.random() * width;
      this.y = -10;
      this.radius = Math.random() * 3 + 1;
      this.speed = Math.random() * 1 + 0.5;
      this.opacity = Math.random() * 0.6 + 0.2;
    }
    
    update() {
      this.y += this.speed;
      // Gentle swaying motion
      this.x += Math.sin(this.y / 30) * 0.5;
      
      if (this.y &gt; height || this.x &lt; 0 || this.x &gt; width) {
        this.reset();
      }
    }
    
    draw() {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
      ctx.fillStyle = `rgba(25, 25, 255, ${this.opacity})`;
      ctx.fill();
    }
  }
  
  // Particle instantiation
  for (let i = 0; i &lt; maxSnowflakes; i++) {
    snowflakes.push(new Snowflake());
  }
  
  function animate() {
    ctx.clearRect(0, 0, width, height);
    
    for (let i = 0; i &lt; snowflakes.length; i++) {
      snowflakes[i].update();
      snowflakes[i].draw();
    }
    requestAnimationFrame(animate);
  }
  
  // Resize handler
  window.addEventListener(&#39;resize&#39;, () =&gt; {
    width = canvas.width = window.innerWidth;
    height = canvas.height = window.innerHeight;
  });
  
  animate();
})();
</code></pre>
<hr>
<h3 id="sample-b-constellation-network">🕸️ Sample B. Constellation Network</h3>
<p>An IT-inspired constellation pattern where floating node particles link with thin translucent lines when they drift close to one another.</p>
<pre><code class="language-javascript">(function() {
  const canvas = document.getElementById(&#39;bg-canvas&#39;);
  if (!canvas) return;
  const ctx = canvas.getContext(&#39;2d&#39;);
  
  let width = canvas.width = window.innerWidth;
  let height = canvas.height = window.innerHeight;
  
  const divisor = (window.bgConfig &amp;&amp; window.bgConfig.mobileThrottleDivisor) || 1;
  const particleCount = Math.floor(80 / divisor);
  const particles = [];
  const connectionDistance = 100;
  
  class Particle {
    constructor() {
      this.x = Math.random() * width;
      this.y = Math.random() * height;
      this.vx = (Math.random() - 0.5) * 0.8;
      this.vy = (Math.random() - 0.5) * 0.8;
      this.radius = Math.random() * 2 + 1.5;
    }
    
    update() {
      this.x += this.vx;
      this.y += this.vy;
      
      // Boundary collision
      if (this.x &lt; 0 || this.x &gt; width) this.vx *= -1;
      if (this.y &lt; 0 || this.y &gt; height) this.vy *= -1;
    }
    
    draw() {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
      ctx.fillStyle = &#39;rgba(99, 102, 241, 0.4)&#39;; // Pastel indigo
      ctx.fill();
    }
  }
  
  for (let i = 0; i &lt; particleCount; i++) {
    particles.push(new Particle());
  }
  
  function drawLines() {
    for (let i = 0; i &lt; particles.length; i++) {
      for (let j = i + 1; j &lt; particles.length; j++) {
        const dx = particles[i].x - particles[j].x;
        const dy = particles[i].y - particles[j].y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        
        if (dist &lt; connectionDistance) {
          const alpha = (connectionDistance - dist) / connectionDistance * 0.18;
          ctx.beginPath();
          ctx.moveTo(particles[i].x, particles[i].y);
          ctx.lineTo(particles[j].x, particles[j].y);
          ctx.strokeStyle = `rgba(99, 102, 241, ${alpha})`;
          ctx.lineWidth = 1;
          ctx.stroke();
        }
      }
    }
  }
  
  function animate() {
    ctx.clearRect(0, 0, width, height);
    for (let i = 0; i &lt; particles.length; i++) {
      particles[i].update();
      particles[i].draw();
    }
    drawLines();
    requestAnimationFrame(animate);
  }
  
  window.addEventListener(&#39;resize&#39;, () =&gt; {
    width = canvas.width = window.innerWidth;
    height = canvas.height = window.innerHeight;
  });
  
  animate();
})();
</code></pre>
<hr>
<h3 id="sample-c-fluid-sine-waves">🌊 Sample C. Fluid Sine Waves</h3>
<p>A relaxing animation showing multiple overlapping pastel wave ripples flowing smoothly near the bottom of the screen.</p>
<pre><code class="language-javascript">(function() {
  const canvas = document.getElementById(&#39;bg-canvas&#39;);
  if (!canvas) return;
  const ctx = canvas.getContext(&#39;2d&#39;);
  
  let width = canvas.width = window.innerWidth;
  let height = canvas.height = window.innerHeight;
  
  let wave1 = {
    y: height * 0.85,
    length: 0.005,
    amplitude: 25,
    frequency: 0.012
  };
  
  let wave2 = {
    y: height * 0.88,
    length: 0.008,
    amplitude: 15,
    frequency: 0.022
  };
  
  let increment = 0;
  
  function animate() {
    ctx.clearRect(0, 0, width, height);
    
    // Draw background wave (translucent teal)
    ctx.beginPath();
    ctx.moveTo(0, height);
    for (let i = 0; i &lt; width; i++) {
      ctx.lineTo(i, wave1.y + Math.sin(i * wave1.length + increment) * wave1.amplitude);
    }
    ctx.lineTo(width, height);
    ctx.fillStyle = &#39;rgba(45, 212, 191, 0.1)&#39;;
    ctx.fill();
    
    // Draw foreground wave (translucent sky-blue)
    ctx.beginPath();
    ctx.moveTo(0, height);
    for (let i = 0; i &lt; width; i++) {
      ctx.lineTo(i, wave2.y + Math.sin(i * wave2.length - increment * 1.5) * wave2.amplitude);
    }
    ctx.lineTo(width, height);
    ctx.fillStyle = &#39;rgba(56, 189, 248, 0.15)&#39;;
    ctx.fill();
    
    // Adjust speed according to device configuration
    const speedFactor = (window.bgConfig &amp;&amp; window.bgConfig.mobileThrottleDivisor) ? 0.3 : 1;
    increment += wave1.frequency * speedFactor;
    
    requestAnimationFrame(animate);
  }
  
  window.addEventListener(&#39;resize&#39;, () =&gt; {
    width = canvas.width = window.innerWidth;
    height = canvas.height = window.innerHeight;
    wave1.y = height * 0.85;
    wave2.y = height * 0.88;
  });
  
  animate();
})();
</code></pre>
<hr>
<h2 id="6-device-specific-mobile-background-configuration">📱 6. Device-Specific Mobile Background Configuration</h2>
<p>Customize your background settings depending on the user environment to optimize system performance.</p>
<ol>
<li><strong>Desktop Background</strong>: Choose <strong>Custom JavaScript</strong> on PC displays to run beautiful canvas animations.</li>
<li><strong>Enable Independent Mobile Settings</strong>: Check the <strong>&quot;Use different background for mobile devices&quot;</strong> toggle located at the bottom of the design editor.</li>
<li><strong>Mobile Optimization</strong>: Under the separate mobile configuration panel, select <strong>Solid</strong> or <strong>Gradient</strong> backgrounds to minimize processor workloads.</li>
<li><strong>Outcome</strong>: Conserves mobile batteries by running lightweight background styles on smartphones, while maintaining visually rich interactive motion rendering for desktop browsers.</li>
</ol>
]]></content:encoded>
            <category>Admin Guide</category>
        </item>
        <item>
            <title><![CDATA[Admin Core Features and Dual Editor Overview]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/admin-guide/admin-core-features</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/admin-guide/admin-core-features</guid>
            <pubDate>Sat, 20 Jun 2026 01:23:13 GMT</pubDate>
            <description><![CDATA[A brief introduction to core admin features including multi-language simultaneous saving, visual and markdown dual editor switching, and device-specific widget placement.]]></description>
            <content:encoded><![CDATA[<h1 id="admin-core-features-and-dual-editor-overview">🎨 Admin Core Features and Dual Editor Overview</h1>
<p>This document provides a brief overview of the core features in the admin console, including multi-language simultaneous publishing, device-specific layout configuration, and real-time design theme settings.</p>
<hr>
<h2 id="1-multi-language-writing-and-dual-editor-support">📝 1. Multi-Language Writing and Dual Editor Support</h2>
<p>When entering the writing menu, a multi-language editor layout is provided, with multiple language tabs arranged side-by-side on a single screen.</p>
<h3 id="batch-multi-language-writing-and-saving">① Batch Multi-Language Writing and Saving</h3>
<ul>
<li><strong>Writing Flow</strong>: Switch between the language tabs (KO, EN, JA, etc.) at the top to write titles, excerpts, slugs (URL paths), and body content for each language.</li>
<li><strong>Batch Saving</strong>: Click the <strong>[Save All Tabs Simultaneously]</strong> button at the bottom to save the content of all languages to the database at once. Languages not explicitly set to <strong>Publish</strong> will be saved as <strong>Drafts</strong>, and any empty language tabs will be skipped.</li>
</ul>
<h3 id="dual-editor-support-visual-vs-markdown">② Dual Editor Support (Visual vs. Markdown)</h3>
<ul>
<li><strong>Visual HTML Editor (Visual)</strong>: A rich-text editor that allows direct formatting and media embedding. Image files can be easily uploaded and inserted via the toolbar button.</li>
<li><strong>Markdown Editor (Markdown)</strong>: Provided for users who prefer markdown syntax. Metadata such as titles, excerpts, categories, and tags are automatically managed in the header using YAML Front Matter (<code>---</code>). Both markdown source and parsed HTML are stored in the database upon saving.</li>
</ul>
<h3 id="automatic-thumbnail-selection">③ Automatic Thumbnail Selection</h3>
<ul>
<li>If no thumbnail image is manually specified, the system automatically analyzes the content to assign a representative image:<ul>
<li><strong>1st Priority</strong>: The first image element found in the body text.</li>
<li><strong>2nd Priority</strong>: If no images are present but a YouTube video link or iframe embed is found, the official high-resolution YouTube thumbnail URL of the video is used.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="2-device-specific-desktopmobile-independent-widget-placement">🧱 2. Device-Specific (Desktop/Mobile) Independent Widget Placement</h2>
<p>The layout editor supports drag-and-drop widget arrangement for sidebars and content areas, allowing you to configure independent widget exposure based on whether visitors are on desktop or mobile devices.</p>
<figure data-align="left"><img src="/images/posts/admin-core-features/desktop/img-admin-guide-admin-core-features-001.webp" alt="img-admin-guide-admin-core-features-001" data-align="left" data-caption="Desktop/Mobile toggle buttons" /><figcaption>Desktop/Mobile toggle buttons</figcaption></figure><h3 id="device-exposure-options">⚙️ Device Exposure Options</h3>
<ol>
<li>Choose the column layout and width ratio in the <strong><code>Blog Structure</code></strong> tab under the <strong><code>Design Editor</code></strong> menu.</li>
<li>Assign device exposure conditions (Device) when adding or modifying widgets:<ul>
<li><strong>Desktop</strong>: Displays the widget only on wider PC screens, preventing unnecessary resource loads on mobile devices.</li>
<li><strong>Mobile</strong>: Hides the widget on PC screens and limits visibility to mobile viewport resolutions.</li>
</ul>
</li>
<li><strong>Effect</strong>: Skipping heavy or redundant widget rendering for mobile visitors optimizes page load times and mobile scrolling performance.</li>
</ol>
<hr>
<h2 id="3-real-time-design-editor-and-theme-settings">🎨 3. Real-Time Design Editor and Theme Settings</h2>
<p>Design theme changes and background configurations apply instantly via CSS variables in the visitor&#39;s browser without requiring server rebuilds or redeployments.</p>
<ul>
<li><strong>4 Background Types</strong>: Select from Solid color, Gradient, Background Image, or interactive HTML5 Canvas animations (Canvas).</li>
<li><strong>Glassmorphism Effect</strong>: When using background images, adjust opacity and blur to ensure text readability with glassmorphism overlays.</li>
<li><strong>Interactive Canvas</strong>: Renders motion artwork (snowflakes, waves, constellations) inside a sandboxed canvas.</li>
</ul>
<blockquote>
<p>[!TIP]<br>Information on background configuration options and script templates can be found in the <strong><a href="./admin-design-editor.md">Design Editor Settings Introduction</a></strong> document.</p>
</blockquote>
<hr>
<h2 id="4-media-storage-support">💾 4. Media Storage Support</h2>
<p>You can switch the active cloud storage provider for uploading and serving media based on your needs.</p>
<ol>
<li>Navigate to the <strong><code>Storage Settings</code></strong> area at the bottom of the <strong><code>Media Library</code></strong> menu.</li>
<li>Select your storage provider and configure the credentials:<ul>
<li><strong>Cloudflare KV</strong>: Stores assets in edge KV storage for fast global delivery.</li>
<li><strong>Cloudflare R2</strong>: Cost-effective large object storage for managing mass images.</li>
<li><strong>Supabase Storage</strong>: Securely uploads and stores media assets in Supabase storage buckets.</li>
<li><strong>ImageKit.io</strong>: Connects global image CDN platforms for real-time optimization and compressed formatting.</li>
</ul>
</li>
<li><strong>Real-time Switch</strong>: Saving changes instantly shifts the active upload engine to the chosen storage provider.</li>
</ol>
<blockquote>
<p>[!NOTE]<br><strong>Limitations of default storage (Cloudflare KV) in media explorer</strong><br>Cloudflare KV does not support directory listing (read APIs) in the image explorer to minimize Workers usage and costs. Other external storages, such as Cloudflare R2, Supabase Storage, and ImageKit.io, fully support listing and previewing uploaded images.</p>
</blockquote>
]]></content:encoded>
            <category>Admin Guide</category>
            <enclosure url="/images/posts/admin-core-features/desktop/img-admin-guide-admin-core-features-001.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[First Access to Admin & Getting Started with Configurations]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/admin-guide/admin-getting-started</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/admin-guide/admin-getting-started</guid>
            <pubDate>Sat, 20 Jun 2026 00:55:48 GMT</pubDate>
            <description><![CDATA[Learn how to safely access the admin app, maintain login sessions, and utilize the multilingual UI dictionary to manage the blog system.]]></description>
            <content:encoded><![CDATA[<h1 id="first-access-to-admin-amp-getting-started-with-configurations">🔑 First Access to Admin &amp; Getting Started with Configurations</h1>
<p>This document guides administrators on how to safely access the admin page, maintain login sessions, and easily manage various site-wide text strings (multilingual dictionary) to control the blog system.</p>
<hr>
<h2 id="1-ip-security-control-policy-before-admin-login">🔒 1. IP Security Control Policy before Admin Login</h2>
<p>This blog engine adheres to a strict <strong>Access IP Filtering</strong> security policy to completely prevent unauthorized external access or hijacking of posting permissions. Only the administrator&#39;s public IP address detected at the time of deployment is registered in the server&#39;s allowlist (<code>ALLOWED_IP</code>) to permit access.</p>
<blockquote>
<p>[!IMPORTANT]</p>
<h3 id="safe-zone-centered-operation-principle-no-use-in-public-places">🛡️ Safe-Zone Centered Operation Principle (No Use in Public Places)</h3>
<p>Admin management of this blog must be performed only in <strong>places where physical and network security are secured, such as home or a trusted private office.</strong><br><strong>To prevent security leaks, accessing the admin page is strictly discouraged and should be avoided in public places such as PC cafes (PC bangs), libraries, or under public Wi-Fi networks, as they are exposed to high security risks.</strong></p>
</blockquote>
<p>If you encounter a <code>403 Forbidden</code> block screen because your public IP address changed due to router rebooting or network conditions within your safe zone, you must manually update the allowlist according to the following procedure.</p>
<h3 id="allowed-ip-list-renewal-procedure-redeployment-required">⚙️ Allowed IP List Renewal Procedure (Redeployment Required)</h3>
<ol>
<li>Open the terminal under the changed internet environment, and run the command to <strong>redeploy</strong> the blog service admin app once again.</li>
<li><strong>Workflow Guide</strong>: While this is safer than forcedly editing the database internals (which is a risky operation), it is a somewhat tedious and inconvenient process because it requires the build process and file upload waiting time of several minutes each time.</li>
<li>While the deployment script is running, it detects the new public IP address of your currently connected computer and replaces the remote server&#39;s allowed IP list with the latest one.</li>
<li>Once the deployment process is finalized, reconnecting to the admin URL will re-enable the normal login screen.</li>
<li>You only need to redeploy the admin page.</li>
</ol>
<hr>
<h2 id="2-admin-login-amp-session-management">🔑 2. Admin Login &amp; Session Management</h2>
<p>Once the login block is normal, enter the master password (<code>ADMIN_PASSWORD</code>) configured during setup to log in.</p>
<ul>
<li><strong>Secure Session Maintenance</strong>: By utilizing dedicated secure cookies, the admin login session remains safely maintained for 30 days.</li>
<li><strong>Prohibition of Access from Public Computers and Risky Areas</strong>:<br>The most secure practice is to never attempt logging in to the admin console on unverified public computers or PC cafes. If you must log in under public conditions, make sure to click the <strong>[Logout]</strong> button at the bottom left of the admin page immediately after completing work, and also enter <code>npx wrangler logout</code> in your terminal to completely sign out from the Cloudflare management credentials on that computer to prevent any credential leaks.</li>
</ul>
<blockquote>
<p>[!WARNING]</p>
<h3 id="minimize-exposure-of-admin-access-address-domain">🔒 Minimize Exposure of Admin Access Address (Domain)</h3>
<p>While the admin console is double-protected by the IP allowlist, minimizing the attack surface itself is the most robust security practice.</p>
<p>Therefore, we strongly recommend that you do not bind an obvious custom domain like <code>admin.myblog.com</code>, but instead use the randomized subdomain URL (e.g., <code>[project-name].pages.dev</code>) provided default by Cloudflare Pages to keep the admin entry hidden.</p>
</blockquote>
<hr>
<h2 id="3-multilingual-dictionary-i18n-settings-guide">🌐 3. Multilingual Dictionary (i18n) Settings Guide</h2>
<p>Fixed common UI text strings (menu labels, comment buttons, login prompts, etc.) outside of post contents can be modified instantly in English, Korean, or Japanese using the admin dictionary editor without editing a single line of source code.</p>
<ol>
<li>Go to the <strong><code>Languages</code></strong> menu on the left sidebar of the admin console.</li>
<li>A list of all dictionary keys and their saved translations used across the site is provided in the <strong><code>UI Dictionary Editor</code></strong> section at the bottom.</li>
<li>Enter your desired text (Korean, English, Japanese) directly into the input field for the key you wish to modify, and click the <strong><code>Save</code></strong> icon on the far right of that row.</li>
<li>Changes apply to the live site immediately upon saving. When visitors switch languages on the blog, the modified texts will be displayed seamlessly in real-time.</li>
</ol>
]]></content:encoded>
            <category>Admin Guide</category>
        </item>
        <item>
            <title><![CDATA[CMD One-Click Installation & Cloudflare Deployment Guide]]></title>
            <link>https://sveltekitblogblog.pages.dev/en/admin-guide/admin-install-and-deploy</link>
            <guid isPermaLink="true">https://sveltekitblogblog.pages.dev/en/admin-guide/admin-install-and-deploy</guid>
            <pubDate>Sat, 20 Jun 2026 00:27:19 GMT</pubDate>
            <description><![CDATA[Learn how to build the Cloudflare edge infrastructure and deploy/sync both admin and blog apps simultaneously using a single interactive setup script in a terminal (CMD/PowerShell) environment.]]></description>
            <content:encoded><![CDATA[<h1 id="cmd-one-click-installation-amp-cloudflare-deployment-guide">🚀 CMD One-Click Installation &amp; Cloudflare Deployment Guide</h1>
<p>This guide explains the easiest and safest way to build the Cloudflare edge infrastructure and deploy/sync both the admin and blog apps simultaneously by running a single automation command (<code>npm run setup</code>) in a terminal (CMD or PowerShell) environment.</p>
<hr>
<h2 id="1-introduction-to-one-click-deployment-automation">🛠️ 1. Introduction to One-Click Deployment Automation</h2>
<p>The SvelteKit blog engine has fully automated the complex process of server resource creation and configuration file editing through an interactive setup tool in the terminal. </p>
<p>After unpacking the blog source code or downloading it to your computer via <code>git clone</code>, open the terminal, navigate to the project root folder, and run the following commands in sequence:</p>
<pre><code class="language-bash"># Install required packages
npm install
</code></pre>
<ul>
<li><strong>Dependency Library Installation</strong>: Enter <code>npm install</code> in the terminal to install all required packages. If a security warning (vulnerabilities) message appears in the terminal after installation is complete, it is recommended to enter the <code>npm audit fix</code> command to safely apply the latest security patches.</li>
</ul>
<p>Once the package installation is complete and you run <code>npm run setup</code>, the following processes will be handled automatically according to the terminal prompts:</p>
<ul>
<li><strong>Easy Cloudflare Account Authentication</strong>: Link your deployment account with a single click.</li>
<li><strong>Create DB and Storage Resources</strong>: Automatically create 2 D1 databases dedicated to the blog and a KV store for storing images.</li>
<li><strong>Real-time Configuration File Update</strong>: Detect the unique IDs of the created databases and automatically inject them into the monorepo configuration files (<code>wrangler.json</code>).</li>
<li><strong>Database Seed Data Injection</strong>: Create tables and automatically register sample posts and basic configuration information according to the selected default language.</li>
<li><strong>Upload Secrets and Allowed IP</strong>: Automatically transmit the deployer&#39;s current public IP address (<code>ALLOWED_IP</code>) and password environment variables to the cloud for admin access.</li>
<li><strong>Integrated Build &amp; Web Service Deployment</strong>: Bundle both the blog and admin SvelteKit projects and immediately deploy them to Cloudflare Pages.</li>
</ul>
<hr>
<h2 id="2-pre-deployment-checklist">📋 2. Pre-deployment Checklist</h2>
<p>Please make sure all of the following are prepared before starting the safe installation:</p>
<ol>
<li><strong>Install Node.js</strong>: Node.js (version 18 or higher) must be working on your computer.</li>
<li><strong>Cloudflare Account</strong>: A Cloudflare account (the free tier is sufficient) is required to host the blog site and databases.</li>
<li><strong>Create Secret Environment Variable Files (.dev.vars) (Required)</strong>:<ul>
<li>Before starting deployment, you must <strong>manually create</strong> a <code>.dev.vars</code> file in each of the <code>apps/admin/</code> and <code>apps/blog/</code> folders.</li>
<li>In the <code>apps/admin/.dev.vars</code> file, write <code>ADMIN_PASSWORD=YourAdminLoginPassword</code>.</li>
<li>In the <code>apps/blog/.dev.vars</code> file, write <code>BETTER_AUTH_SECRET=ArbitraryStringOfYourChoice</code>.</li>
<li><blockquote>
<p>[!WARNING]<br>If these environment variables are not set, the <strong>installation tool will stop</strong> immediately for correct operation upon running <code>npm run setup</code>.</p>
</blockquote>
</li>
</ul>
</li>
</ol>
<hr>
<h2 id="3-step-by-step-guide-for-npm-run-setup">⚙️ 3. Step-by-Step Guide for npm run setup</h2>
<p>Open the terminal, type <code>npm run setup</code> in the blog project root directory, and press Enter.</p>
<h3 id="step-0-secrets-pre-validation"><strong>Step 0. Secrets Pre-Validation</strong></h3>
<ul>
<li>Immediately upon execution, it checks if the <code>.dev.vars</code> files and the required secret variables (<code>ADMIN_PASSWORD</code>, <code>BETTER_AUTH_SECRET</code>) are entered in the admin and blog folders.</li>
<li>If any value is missing, the guide log is displayed and the script exits, so please make sure to fill them in advance.</li>
</ul>
<h3 id="step-1-configure-deployment-project-name-domain-url"><strong>Step 1. Configure Deployment Project Name (Domain URL)</strong></h3>
<ul>
<li>This step defines the URL that readers will use to access your blog (e.g., <code>[entered-project-name].pages.dev</code>).</li>
<li>It takes two names: one for the blog and one for the admin app. If running in restore mode (<code>--restore</code>), it automatically reads the existing names from the backup configuration file (<code>wrangler.backup.json</code>).</li>
</ul>
<h3 id="step-2-cloudflare-account-authentication"><strong>Step 2. Cloudflare Account Authentication</strong></h3>
<ul>
<li>Verifies Cloudflare authentication. If you have logged in previously, it automatically detects the session and skips this step.</li>
<li>If you are not logged in, a browser window will open showing the authentication request screen. Click <strong>[Allow]</strong> to approve the account integration.</li>
<li><em>Security Information: This automation tool only requests the minimum account API permissions required for infrastructure creation and deployment, so you can proceed with confidence.</em></li>
</ul>
<h3 id="step-3-resource-creation-amp-configuration-binding"><strong>Step 3. Resource Creation &amp; Configuration Binding</strong></h3>
<ul>
<li>This step creates the database and media storage in the cloud for the actual service to run. Look at the prompts in the terminal and enter the appropriate number.<ol>
<li><strong><code>1</code> (Fresh Install)</strong>: <strong>Completely deletes</strong> previously created databases and storage and recreates them. Please note that all existing data will be lost.</li>
<li><strong><code>2</code> (Keep Existing Data) [Recommended]</strong>: If resources already exist, it safely preserves the data and only links the connection information.</li>
</ol>
</li>
<li>Upon completion, the newly issued unique DB and KV IDs are automatically updated in each configuration file (<code>wrangler.json</code>) of the monorepo.</li>
</ul>
<h3 id="step-4-pre-create-web-projects"><strong>Step 4. Pre-create Web Projects</strong></h3>
<ul>
<li>To improve deployment reliability, it pre-registers and reserves empty web projects on Cloudflare Edge.</li>
<li>If a domain with the same name is already occupied, it <strong>reuses the existing domain</strong> and automatically transitions to the next step safely.</li>
</ul>
<h3 id="step-5-remote-sync-of-secrets"><strong>Step 5. Remote Sync of Secrets</strong></h3>
<ul>
<li>Safely uploads and synchronizes the secret values, such as the master password written locally in <code>.dev.vars</code>, to Cloudflare.</li>
<li><strong>Automatic Access IP Registration</strong>: Especially in this step, it detects the public IP address of the administrator&#39;s computer running the deployment in real-time and automatically injects it as the <code>ALLOWED_IP</code> variable. This prevents the administrator from being blocked upon accessing the login screen immediately after deployment.</li>
</ul>
<h3 id="step-6-database-table-configuration-amp-default-theme-setup"><strong>Step 6. Database Table Configuration &amp; Default Theme Setup</strong></h3>
<ul>
<li>Configure the database tables needed for the blog to function and inject default settings.</li>
<li>Following the on-screen prompts, choose your primary language (Korean, English, Japanese). This sets up the translation system, sample categories, header menu structure, and a default welcome post automatically.</li>
</ul>
<h3 id="step-7-build-web-services-amp-final-deployment"><strong>Step 7. Build Web Services &amp; Final Deployment</strong></h3>
<ul>
<li>Performs the integrated build of all monorepo apps and automatically runs the deployment command to Cloudflare servers to complete the installation process. Once deployment is complete, the Pages URLs for both the blog and admin will be displayed.</li>
</ul>
<hr>
<blockquote>
<p>[!TIP]</p>
<h3 id="automatic-secret-settings-and-immediate-connection-support">💡 Automatic Secret Settings and Immediate Connection Support</h3>
<p>The installation process of this project seamlessly handles resource creation, web project provisioning, and secret environment variable transmission.<br>Upon completion, the login password and IP permission settings are perfectly configured on the remote server, so it works immediately without any additional manual configuration.</p>
</blockquote>
<hr>
<h2 id="4-blog-update-amp-data-restore-deployment-npm-run-restore">🔄 4. Blog Update &amp; Data Restore Deployment (npm run restore)</h2>
<p>When a <strong>new patch version or a bug-fixed release code is deployed</strong> while running your blog, this process allows you to safely transfer your existing post data and URLs without data loss while replacing the screen with the new code.</p>
<h3 id="4-step-migration-procedure-for-new-versions">💡 4-Step Migration Procedure for New Versions</h3>
<p>You can safely complete the upgrade without data loss by using the admin data backup and the <strong><code>npm run restore</code></strong> command.</p>
<ol>
<li><strong>[Step 1] Backup Existing Data &amp; Deployment Settings</strong>:<ul>
<li>Access the <strong><code>Backup</code></strong> menu and the backup section at the bottom of the <strong><code>Theme Editor</code></strong> menu of your active admin app, and download the post content data and theme design settings to your computer respectively.</li>
<li>Also, click the &#39;Download Settings Backup&#39; button in the <strong><code>Backup</code></strong> menu to save the [wrangler.backup.json] file to your PC. (This is the most critical file for maintaining the link to your existing production database&#39;s unique ID.)</li>
</ul>
</li>
<li><strong>[Step 2] Isolated Testing of New Code</strong>:<ul>
<li>In the newly downloaded version&#39;s code folder, run <code>npm run setup</code> and enter a <strong>temporary DB for testing</strong> and a <strong>temporary Pages deployment name for testing</strong> to deploy it separately.</li>
<li>Log in to the newly deployed test admin, and import the backup data files saved in Step 1 to verify that the data loads successfully in advance.</li>
</ul>
</li>
<li><strong>[Step 3] Restore Bindings to Existing Production Server (<code>npm run restore</code>)</strong>:<ul>
<li>Once verification is complete, copy and paste the <code>wrangler.backup.json</code> file saved in Step 1 into the root directory of the new version&#39;s project folder.</li>
<li>Run the <strong><code>npm run restore</code></strong> command in the terminal. The tool script will read the <strong>existing production DB and KV unique ID information</strong> written in the backup file and automatically connect them to the new code&#39;s configuration files via override.</li>
</ul>
</li>
<li><strong>[Step 4] Schema Synchronization &amp; Override Deployment</strong>:<ul>
<li>The restore script safely updates only the table structure schema of the existing production DB to the latest specifications, so <strong>actual posts or data already stored will not be corrupted or deleted</strong> and will be perfectly preserved.</li>
<li>Next, run <code>npm run deploy:blog</code> and <code>npm run deploy:admin</code> respectively. The latest upgraded blog system will be safely deployed, overwriting the system while keeping the same URLs you were using.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="5-backup-file-types-and-functions">📦 5. Backup File Types and Functions</h2>
<p>Refer to the table below for the roles of individual files that can be safely imported and exported from the admin backup menu.</p>
<table>
<thead>
<tr>
<th align="left">Backup Type</th>
<th align="left">Extraction Path</th>
<th align="left">Recommended Filename Example</th>
<th align="left">Detailed Feature &amp; Preserved Content</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><strong>1. Content DB Data</strong></td>
<td align="left"><strong><code>Backup</code></strong> Menu</td>
<td align="left"><code>blog-content-backup-[date].json</code></td>
<td align="left">Preserves all written blog post content, created category information, tag lists, and basic system settings.</td>
</tr>
<tr>
<td align="left"><strong>2. Deployment Config Backup</strong></td>
<td align="left"><strong><code>Backup</code></strong> Menu</td>
<td align="left"><code>wrangler.backup.json</code></td>
<td align="left">Safely preserves the deployment name and unique UUID information required for Cloudflare D1 DB and KV storage binding (<strong>Essential for server migration</strong>).</td>
</tr>
<tr>
<td align="left"><strong>3. Media File Backup</strong></td>
<td align="left"><code>Media Backup &amp; Restore</code> section in the <strong><code>Backup</code></strong> menu<br>or <code>[Backup / Restore]</code> button in the top right of the <strong><code>Media Library</code></strong> menu</td>
<td align="left"><code>[storage-name]-images-backup-[date].zip</code> <br>(e.g., <code>r2-images-backup-[date].zip</code>)</td>
<td align="left">Downloads and preserves all image media files uploaded to the active image storage (R2, Supabase, etc.) as a ZIP file.</td>
</tr>
<tr>
<td align="left"><strong>4. Design Settings Backup</strong></td>
<td align="left">Bottom of <strong><code>Theme Editor</code></strong> menu</td>
<td align="left"><code>blog-design-backup-[date].json</code></td>
<td align="left">Preserves blog theme color information, background types, and device-specific (desktop/mobile) widget layout structures configured in the Theme Editor.</td>
</tr>
<tr>
<td align="left"><strong>5. Full System Backup</strong></td>
<td align="left">Bottom of <strong><code>Site Settings</code></strong> menu</td>
<td align="left"><code>full-system-backup-[date].json</code></td>
<td align="left">Gathers raw data of all tables from both databases (BLOG_DB, USER_DB) into a single JSON file for a complete backup and restore.</td>
</tr>
</tbody></table>
]]></content:encoded>
            <category>Admin Guide</category>
        </item>
    </channel>
</rss>