<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tianya School Technical Articles]]></title><description><![CDATA[Welcome to our tech publication, where we share high-quality content on full-stack development, frontend/backend/web3/AI, and engineering best practices.]]></description><link>https://tech.tianyaschool.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1751734301934/e99b1009-c9cc-4c17-a1a4-37bd2f547194.png</url><title>Tianya School Technical Articles</title><link>https://tech.tianyaschool.com</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 19:13:50 GMT</lastBuildDate><atom:link href="https://tech.tianyaschool.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[PWA Offline Storage Strategies-IndexedDB and Cache API]]></title><description><![CDATA[Progressive Web Apps (PWAs) utilize offline storage strategies to provide an offline experience, enabling access to some content even when the network is unavailable. The two primary offline storage t]]></description><link>https://tech.tianyaschool.com/pwa-offline-storage-strategies-indexeddb-and-cache-api</link><guid isPermaLink="true">https://tech.tianyaschool.com/pwa-offline-storage-strategies-indexeddb-and-cache-api</guid><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 09 Mar 2026 15:18:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68537656fa49210316116f5d/11d71fd6-98a4-4c5e-a311-b759de150d53.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Progressive Web Apps (PWAs) utilize offline storage strategies to provide an offline experience, enabling access to some content even when the network is unavailable. The two primary offline storage technologies are <strong>IndexedDB</strong> and the <strong>Cache API</strong> (also known as Service Worker Cache). Each has distinct features and is suited for different use cases.</p>
<h3>IndexedDB</h3>
<p>IndexedDB is a key-value store ideal for storing large amounts of structured data, such as database records, user settings, or large files. It supports complex queries and transactional operations. Below is an example of creating, storing, and retrieving data with IndexedDB:</p>
<pre><code class="language-javascript">// Open or create a database
let dbPromise = indexedDB.open("myDatabase", 1);

// When the database opens successfully
dbPromise.then(function(db) {
    // Create an object store
    let objectStore = db.createObjectStore("myStore", { keyPath: "id" });

    // Insert data
    objectStore.add({ id: 1, name: "Alice" });

    // Query data
    let transaction = db.transaction(["myStore"], "readonly");
    let store = transaction.objectStore("myStore");
    let request = store.get(1);

    request.onsuccess = function(event) {
        console.log("Retrieved data:", event.target.result);
    };
});
</code></pre>
<h3>Cache API</h3>
<p>The Cache API, part of Service Workers, is used to cache network requests and responses, typically for static resources. It provides a straightforward way to store and retrieve resources based on their URLs. Below is an example of using the Cache API to cache web resources:</p>
<pre><code class="language-javascript">// Cache resources during the install phase in the service worker
self.addEventListener("install", async event =&gt; {
    event.waitUntil(
        caches.open("myCache").then(cache =&gt; {
            return cache.addAll([
                "/index.html",
                "/styles.css",
                "/scripts.js"
            ]);
        })
    );
});

// Handle fetch events by attempting to retrieve resources from the cache
self.addEventListener("fetch", event =&gt; {
    event.respondWith(
        caches.match(event.request).then(response =&gt; {
            // Return cached response if available
            if (response) {
                return response;
            } else {
                // Otherwise, fetch from the network and cache the new resource
                return fetch(event.request).then(networkResponse =&gt; {
                    caches.open("myCache").then(cache =&gt; {
                        cache.put(event.request, networkResponse.clone());
                    });
                    return networkResponse;
                }).catch(() =&gt; {
                    // Return a cached fallback response if the network fails
                    return caches.match("/offline.html");
                });
            }
        })
    );
});
</code></pre>
<p><strong>Code Breakdown</strong>:</p>
<ul>
<li><p>The <code>install</code> event initializes the cache, adding specified URLs to it.</p>
</li>
<li><p>The <code>fetch</code> event listens for network requests, prioritizing cached resources. If no cache exists, it fetches from the network, caches the new resource, and returns it. If the network request fails, a fallback offline page is returned.</p>
</li>
</ul>
<p>By combining IndexedDB and the Cache API, PWAs can store both user data and static resources offline, ensuring a robust user experience even without a network connection.</p>
<p>In real-world PWA applications, IndexedDB and the Cache API are often used together to achieve optimal offline experiences. For example, IndexedDB stores user data, while the Cache API handles static resources.</p>
<pre><code class="language-javascript">self.addEventListener("install", async event =&gt; {
    event.waitUntil(
        Promise.all([
            caches.open("staticCache").then(cache =&gt; {
                return cache.addAll([
                    "/index.html",
                    "/styles.css",
                    "/scripts.js"
                ]);
            }),
            // Assume an API fetches user data
            fetch("/api/user").then(response =&gt; {
                return response.json().then(data =&gt; {
                    return indexedDB.open("userData", 1).then(db =&gt; {
                        let transaction = db.transaction(["userData"], "readwrite");
                        let store = transaction.objectStore("userData");
                        store.put(data);
                    });
                });
            })
        ])
    );
});

self.addEventListener("fetch", event =&gt; {
    event.respondWith(
        caches.match(event.request).then(response =&gt; {
            if (response) {
                return response;
            }

            // Try fetching from the network
            return fetch(event.request).then(networkResponse =&gt; {
                caches.open("staticCache").then(cache =&gt; {
                    cache.put(event.request, networkResponse.clone());
                });

                return networkResponse;
            }).catch(() =&gt; {
                // If network fails, try fetching user data from IndexedDB
                if (event.request.url.endsWith("/api/user")) {
                    return indexedDB.open("userData", 1).then(db =&gt; {
                        let transaction = db.transaction(["userData"], "readonly");
                        let store = transaction.objectStore("userData");
                        let request = store.get(1);
                        return request.onsuccess ? request.onsuccess.event.target.result : null;
                    });
                } else {
                    return caches.match("/offline.html");
                }
            });
        })
    );
});
</code></pre>
<p><strong>Code Breakdown</strong>:</p>
<ol>
<li><p>During the <code>install</code> event, static resources are cached, and user data is fetched from an API and stored in IndexedDB.</p>
</li>
<li><p>During the <code>fetch</code> event, resources are first retrieved from the cache. If unavailable, the network is queried. For API requests, if the network fails, user data is retrieved from IndexedDB. For other resources, a fallback offline page is returned.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[WebGL and Three.js-3D Graphics Applications on the Web]]></title><description><![CDATA[WebGL (Web Graphics Library) is a JavaScript API that enables hardware-accelerated 3D graphics rendering in any compatible web browser without the need for plugins. Based on the OpenGL standard, it in]]></description><link>https://tech.tianyaschool.com/webgl-and-three-js-3d-graphics-applications-on-the-web</link><guid isPermaLink="true">https://tech.tianyaschool.com/webgl-and-three-js-3d-graphics-applications-on-the-web</guid><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 09 Mar 2026 15:01:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68537656fa49210316116f5d/ebfc1ad1-ce15-44f5-ad19-c21350e808cc.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>WebGL (Web Graphics Library) is a JavaScript API that enables hardware-accelerated 3D graphics rendering in any compatible web browser without the need for plugins. Based on the OpenGL standard, it integrates directly with HTML5’s Canvas element. WebGL allows developers to create complex 3D visual effects on web pages.</p>
<p>Three.js is a popular JavaScript library that encapsulates the complexity of WebGL, providing a more user-friendly interface for creating 3D content. It simplifies low-level WebGL tasks such as vertex buffer management, shader handling, and texture loading, allowing developers to focus on building 3D scenes and interactions.</p>
<h3>Basic Steps for Creating a 3D Scene with Three.js</h3>
<h4>1. Set Up the HTML Structure</h4>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Three.js Scene&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r137/three.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
    // JavaScript code will go here
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This includes the Three.js library via a CDN link.</p>
<h4>2. Initialize Scene, Camera, and Renderer</h4>
<pre><code class="language-javascript">const scene = new THREE.Scene(); // Create a scene
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // Create a perspective camera
const renderer = new THREE.WebGLRenderer(); // Create a renderer
renderer.setSize(window.innerWidth, window.innerHeight); // Set renderer size
document.body.appendChild(renderer.domElement); // Add renderer output to the page
</code></pre>
<p>The <strong>Scene</strong> is a container for all 3D objects, the <strong>Camera</strong> defines the viewpoint of the 3D world, and the <strong>Renderer</strong> is responsible for rendering the scene to the screen.</p>
<h4>3. Create 3D Objects</h4>
<pre><code class="language-javascript">const geometry = new THREE.BoxGeometry(1, 1, 1); // Create a cube geometry
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // Create a basic material, colored green
const cube = new THREE.Mesh(geometry, material); // Create a mesh combining geometry and material
scene.add(cube); // Add to the scene
</code></pre>
<p>This creates a basic cube mesh object.</p>
<h4>4. Animation Loop</h4>
<pre><code class="language-javascript">function animate() {
  requestAnimationFrame(animate); // Use requestAnimationFrame for per-frame updates
  cube.rotation.x += 0.01; // Update cube rotation
  cube.rotation.y += 0.01;
  renderer.render(scene, camera); // Render the scene
}
animate(); // Start the animation
</code></pre>
<p>The animation loop uses <code>requestAnimationFrame</code> to update the cube’s rotation and re-render the scene each frame.</p>
<h4>5. Lighting and Shaders</h4>
<p>Three.js supports various light sources and custom shaders, enabling complex lighting effects and custom surface appearances for 3D objects.</p>
<h4>6. Interactivity</h4>
<p>Interactivity with 3D objects, such as dragging, scaling, or rotating, can be implemented by listening to mouse and touch events.</p>
<h4>7. Textures and Materials</h4>
<p>Textures can be added to 3D objects by loading image files, enhancing visual realism.</p>
<h4>8. Loading 3D Models</h4>
<p>Three.js supports loading external 3D model files in formats like <code>.obj</code>, <code>.gltf</code>, and others.</p>
<h4>9. Animation and Keyframes</h4>
<ul>
<li><p><code>THREE.AnimationMixer</code>: Used to create complex animation sequences by controlling 3D object properties via keyframes.</p>
</li>
<li><p><code>THREE.KeyframeTrack</code>: Defines property values at specific time points.</p>
</li>
<li><p><code>THREE.AnimationClip</code>: Combines multiple keyframe tracks into a complete animation segment.</p>
</li>
</ul>
<h4>10. Camera Controllers</h4>
<p>Three.js provides camera controllers like <code>OrbitControls</code> and <code>FirstPersonControls</code>, facilitating user-controlled panning, rotation, and zooming in 3D space.</p>
<h4>11. Lighting System</h4>
<ul>
<li><p><code>THREE.PointLight</code>, <code>THREE.DirectionalLight</code>, <code>THREE.SpotLight</code>, and <code>THREE.AmbientLight</code> represent point lights, directional lights, spotlights, and ambient lights, respectively.</p>
</li>
<li><p><code>THREE.LightShadow</code> enables shadow effects for light sources.</p>
</li>
</ul>
<h4>12. Particle Systems</h4>
<ul>
<li><p><code>THREE.ParticleSystem</code> and <code>THREE.Points</code> create particle effects like smoke, sparks, or raindrops.</p>
</li>
<li><p>Combined with <code>THREE.Geometry</code> and <code>THREE.PointsMaterial</code>, particle shapes and appearances can be customized.</p>
</li>
</ul>
<h4>13. Texture Mapping</h4>
<ul>
<li><p><code>THREE.TextureLoader</code>: Loads texture images.</p>
</li>
<li><p><code>THREE.CubeTextureLoader</code>: Loads cube maps, commonly used for environment mapping.</p>
</li>
<li><p><code>THREE.VideoTexture</code>: Uses video as a texture for 3D objects.</p>
</li>
</ul>
<h4>14. Geometries</h4>
<p>In addition to basic geometries (e.g., <code>BoxGeometry</code>, <code>SphereGeometry</code>), Three.js supports creating complex shapes like toruses, cylinders, and cones. The <code>THREE.Geometry.merge()</code> method allows combining multiple geometries.</p>
<h4>15. Physics Engine Integration</h4>
<p>Third-party libraries like Cannon.js or Ammo.js can integrate physics simulations (e.g., collision detection, gravity) into Three.js scenes.</p>
<h4>16. Custom Shaders</h4>
<p>Three.js supports GLSL (OpenGL Shading Language) shaders, allowing developers to write custom vertex and fragment shaders for complex lighting and surface effects.</p>
<h4>17. WebVR and WebXR</h4>
<p>For virtual reality (VR) and augmented reality (AR), Three.js provides <code>WebVRManager</code> and <code>WebXRManager</code> to create immersive experiences on compatible devices.</p>
<h3>Example: Creating a 3D Application with Three.js</h3>
<p>Here’s a complete example of a 3D cube application using Three.js, including scene setup, camera, renderer, geometry, material, and animation loop:</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Three.js Cube Example&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r137/three.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
    // Create scene
    const scene = new THREE.Scene();
    
    // Create camera
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 5;
    
    // Create renderer
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    // Create cube
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    
    // Animation loop
    function animate() {
      requestAnimationFrame(animate);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
    }
    animate();
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p><strong>Code Breakdown</strong>:</p>
<ol>
<li><p><strong>Include Three.js Library</strong>: The latest Three.js version (v0.137.0) is included via CDN.</p>
</li>
<li><p><strong>Create Scene, Camera, and Renderer</strong>:</p>
<ul>
<li><p><code>THREE.Scene</code>: The container for all 3D objects.</p>
</li>
<li><p><code>THREE.PerspectiveCamera</code>: Creates a perspective camera with parameters for field of view, aspect ratio, near clipping plane, and far clipping plane.</p>
</li>
<li><p><code>THREE.WebGLRenderer</code>: Sets up the renderer, configures its size, and adds it to the HTML page.</p>
</li>
</ul>
</li>
<li><p><strong>Create Cube</strong>:</p>
<ul>
<li><p><code>THREE.BoxGeometry</code>: Creates a unit cube geometry.</p>
</li>
<li><p><code>THREE.MeshBasicMaterial</code>: Defines a basic material with a green color.</p>
</li>
<li><p><code>THREE.Mesh</code>: Combines geometry and material into a renderable mesh.</p>
</li>
</ul>
</li>
<li><p><strong>Set Camera Position</strong>: Moves the camera 5 units along the Z-axis to view the cube from the side.</p>
</li>
<li><p><strong>Animation Loop</strong>:</p>
<ul>
<li><p><code>requestAnimationFrame(animate)</code>: Calls the <code>animate</code> function on the next browser repaint for smooth animations.</p>
</li>
<li><p>Updates the cube’s X and Y rotation angles each frame to rotate the cube.</p>
</li>
<li><p><code>renderer.render(scene, camera)</code>: Renders the scene using the current camera perspective.</p>
</li>
</ul>
</li>
</ol>
<h3>Creating a 3D Application with WebGL</h3>
<p>Creating a 3D application with raw WebGL involves multiple steps, including setting up the context, creating geometries, defining materials, configuring the camera, setting up lighting, and implementing a render loop.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;WebGL Example&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;canvas id="glCanvas" width="800" height="600"&gt;&lt;/canvas&gt;
  &lt;script&gt;
    // WebGL code will go here
    const canvas = document.getElementById('glCanvas');
    const gl = canvas.getContext('webgl');
    
    if (!gl) {
      alert('WebGL not supported');
    }
    
    // Further WebGL setup and rendering logic
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Deno Introduction-A Modern Alternative to Node.js]]></title><description><![CDATA[Deno, as a modern alternative to Node.js, offers numerous improvements and innovations, particularly in security, module systems, and developer experience. Although still in development, Deno is a com]]></description><link>https://tech.tianyaschool.com/deno-introduction-a-modern-alternative-to-node-js</link><guid isPermaLink="true">https://tech.tianyaschool.com/deno-introduction-a-modern-alternative-to-node-js</guid><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 09 Mar 2026 14:59:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68537656fa49210316116f5d/e6c67bb6-fa06-4eff-b253-96e60f24b50b.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Deno, as a modern alternative to Node.js, offers numerous improvements and innovations, particularly in security, module systems, and developer experience. Although still in development, Deno is a compelling choice for developers seeking a simple, secure, and modern JavaScript/TypeScript development environment. As its community continues to grow, Deno’s potential and influence are expected to expand further.</p>
<h3>Deno Fundamentals</h3>
<ul>
<li><p><strong>Built-in Security Model</strong>: Deno enforces strict permission controls, requiring explicit permissions for actions like file read/write or network access.</p>
</li>
<li><p><strong>TypeScript Support</strong>: Deno natively supports TypeScript, providing enhanced type checking and a better development experience.</p>
</li>
<li><p><strong>ES Modules</strong>: Deno uses URLs or import maps for module imports, differing from Node.js’s CommonJS module system.</p>
</li>
</ul>
<h4>Command-Line Tools</h4>
<ul>
<li><p><code>deno run</code>: Executes a single file.</p>
</li>
<li><p><code>deno test</code>: Runs tests.</p>
</li>
<li><p><code>deno fmt</code>: Formats code.</p>
</li>
<li><p><code>deno lint</code>: Checks code style.</p>
</li>
</ul>
<h4>Configuration File</h4>
<p>Deno’s configuration is primarily managed through the <code>deno.json</code> file, which allows customization of runtime behavior. Environment variables mainly affect Deno’s global configuration, such as logging levels or cache directories.</p>
<p><strong>Deno Configuration File (deno.json)</strong></p>
<p>The configuration file typically includes the following sections:</p>
<ol>
<li><p><strong>permissions</strong>: Defines runtime permissions.</p>
</li>
<li><p><strong>importMap</strong>: Configures module import mappings.</p>
</li>
<li><p><strong>compilerOptions</strong>: TypeScript compiler options.</p>
</li>
<li><p><strong>lintRules</strong>: Linting rules (if using deno-lint).</p>
</li>
<li><p><strong>watch</strong>: Monitors file changes and automatically re-runs.</p>
</li>
<li><p><strong>reload</strong>: Automatically reloads modules.</p>
</li>
</ol>
<pre><code class="language-json">{
  "permissions": {
    "env": true,
    "net": ["*"],
    "read": ["./data"],
    "write": ["./output"]
  },
  "importMap": {
    "imports": {
      "lodash": "https://cdn.skypack.dev/lodash@4.17.21",
      "my-local-module": "./src/my-local-module.ts"
    }
  },
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "lib": ["dom", "deno.ns"],
    "strict": true
  },
  "lintRules": {
    // ...
  },
  "watch": true,
  "reload": {
    "enabled": true,
    "include": ["./src"]
  }
}
</code></pre>
<h4>Environment Variables</h4>
<ul>
<li><p><code>DENO_DIR</code>: Specifies the configuration, cache, and download directory, defaulting to <code>~/.deno</code>.</p>
</li>
<li><p><code>DENO_AUTH_TOKEN</code>: Authentication token for accessing private modules.</p>
</li>
<li><p><code>DENO_LOGGING_LEVEL</code>: Controls logging level, e.g., <code>debug</code>, <code>info</code>, <code>warn</code>, <code>error</code>.</p>
</li>
<li><p><code>DENO_CACHE</code>: Custom cache directory.</p>
</li>
<li><p><code>DENO.land_proxy</code>: Proxy settings for accessing deno.land.</p>
</li>
<li><p><code>DENO_NO_COLOR</code>: Disables colored output if set.</p>
</li>
</ul>
<pre><code class="language-bash"># Linux/MacOS
export DENO_DIR=/path/to/custom/deno/dir
export DENO_LOGGING_LEVEL=debug

# Windows
set DENO_DIR=%USERPROFILE%\custom\deno\dir
set DENO_LOGGING_LEVEL=debug
</code></pre>
<p>Note that not all configuration options can be set via environment variables; most configurations are defined in the <code>deno.json</code> file. Deno’s permissions are typically specified at runtime via command-line flags, not through configuration files or environment variables. For example: <code>deno run --allow-read=./data your_script.ts</code>.</p>
<h3>Creating an HTTP Server</h3>
<p>Creating an HTTP server in Deno is straightforward using the built-in <code>std/http</code> library.</p>
<pre><code class="language-typescript">// server.ts
import { serve } from "https://deno.land/std/http/server.ts";

const s = serve({ port: 8000 });
console.log("Server is running on http://localhost:8000");

for await (const req of s) {
  req.respond({ status: 200, body: "Hello, World!\n" });
}
</code></pre>
<p><strong>Code Breakdown</strong>:</p>
<ol>
<li><p><strong>Import the</strong> <code>serve</code> <strong>Function</strong>: <code>import { serve } from "https://deno.land/std/http/server.ts";</code> imports the <code>serve</code> function from Deno’s standard library to create an HTTP server.</p>
</li>
<li><p><strong>Start the Server</strong>: <code>const s = serve({ port: 8000 });</code> creates and starts a server listening on port 8000. <code>s</code> is an iterable object representing each incoming request.</p>
</li>
<li><p><strong>Log Server Info</strong>: <code>console.log("Server is running on http://localhost:8000");</code> informs users that the server is running and provides the access URL.</p>
</li>
<li><p><strong>Handle Requests</strong>: <code>for await (const req of s)</code> is an async iterator that waits for and processes each incoming HTTP request. <code>req</code> is a <code>ServerRequest</code> instance containing request details.</p>
</li>
<li><p><strong>Respond to Requests</strong>: <code>req.respond({ status: 200, body: "Hello, World!\n" });</code> sends a response to the client with a 200 status code and a body of "Hello, World!\n".</p>
</li>
<li><p><strong>Run the Server</strong>: In the terminal, run the script with <code>deno run --allow-net server.ts</code>. The <code>--allow-net</code> flag is required to allow network access.</p>
</li>
</ol>
<h3>Fetching Remote Data</h3>
<p>Fetching remote data in Deno typically uses the <code>fetch</code> API:</p>
<pre><code class="language-typescript">// fetch_data.ts
import { assert } from "https://deno.land/std/testing/asserts.ts";
import { json as parseJson } from "https://deno.land/std/io/ioutil.ts";

async function fetchData(url: string) {
  const response = await fetch(url);
  assert(response.ok, `Failed to fetch data: ${response.statusText}`);

  const data = await parseJson(await response.text());
  console.log(data);
}

// Example URL, replace with your desired data source
const remoteDataURL = "https://jsonplaceholder.typicode.com/todos/1";
fetchData(remoteDataURL);
</code></pre>
<p><strong>Code Breakdown</strong>:</p>
<h4>Importing Modules:</h4>
<ul>
<li><p><code>assert</code> ensures the HTTP request succeeds.</p>
</li>
<li><p><code>parseJson</code> converts received text to a JSON object.</p>
</li>
</ul>
<h4>Defining the <code>fetchData</code> Function:</h4>
<ul>
<li><p><code>fetch(url)</code> asynchronously sends an HTTP GET request to the specified URL.</p>
</li>
<li><p><code>response.ok</code> checks if the HTTP status code is in the 200-299 range, indicating success.</p>
</li>
<li><p><code>response.text()</code> retrieves the response body as text.</p>
</li>
<li><p><code>parseJson(text)</code> parses the text into a JSON object.</p>
</li>
<li><p><code>console.log(data)</code> logs the parsed data.</p>
</li>
</ul>
<h4>Calling <code>fetchData</code>:</h4>
<ul>
<li><code>fetchData(remoteDataURL)</code> calls the function with an example URL to fetch remote data.</li>
</ul>
<h4>Running the Script:</h4>
<ul>
<li>Run with <code>deno run --allow-net fetch_data.ts</code>. The <code>--allow-net</code> flag is required for network access.</li>
</ul>
<h3>File System Operations</h3>
<pre><code class="language-typescript">// file_operations.ts
import { readTextFile, writeTextFile } from "https://deno.land/std/fs/mod.ts";

// Read a file
const content = await readTextFile("example.txt");
console.log(content);

// Write to a file
const newContent = "This is new content.";
await writeTextFile("example.txt", newContent);
</code></pre>
<h3>Network Programming</h3>
<pre><code class="language-typescript">// http_server.ts
import { serve } from "https://deno.land/std/http/server.ts";

const s = serve({ port: 8000 });

console.log("Server is running on http://localhost:8000");

for await (const req of s) {
  req.respond({ status: 200, body: "Hello, World!\n" });
}
</code></pre>
<h3>Asynchronous Programming</h3>
<p>Deno uses <code>async/await</code> syntax for asynchronous operations, making code cleaner and easier to understand.</p>
<pre><code class="language-typescript">// async_example.ts
import { delay } from "https://deno.land/std/async/mod.ts";

async function asyncTask() {
  console.log("Task started...");
  await delay(1000); // Delay for 1 second
  console.log("Task completed.");
}

asyncTask();
</code></pre>
<h4>Asynchronous File Operations</h4>
<pre><code class="language-typescript">// async_file.ts
import { ensureDir, readTextFile, writeTextFile } from "https://deno.land/std/fs/mod.ts";
import { delay } from "https://deno.land/std/async/mod.ts";

async function asyncFileOps() {
  try {
    await ensureDir("output"); // Ensure directory exists
    const content = await readTextFile("input.txt");
    console.log("Read content:", content);

    const newContent = "New content";
    await writeTextFile("output/output.txt", newContent);
    console.log("Wrote new content to output file.");

    await delay(2000); // Delay for 2 seconds
    console.log("Finished async operations.");
  } catch (err) {
    console.error("An error occurred:", err);
  }
}

asyncFileOps();
</code></pre>
<h3>Modules and Standard Library</h3>
<p>Deno’s module system is based on ES Modules, allowing code import and export via URLs. Deno’s standard library provides useful modules for file system operations, networking, HTTP servers, JSON processing, encryption, and more.</p>
<h4>Importing Standard Library Modules:</h4>
<pre><code class="language-typescript">// import_std.ts
import { readTextFile } from "https://deno.land/std/fs/mod.ts";
import { serve } from "https://deno.land/std/http/server.ts";

// Read a file using readTextFile
const content = await readTextFile("example.txt");
console.log(content);

// Create an HTTP server
const s = serve({ port: 8000 });
console.log("Server is running on http://localhost:8000");

for await (const req of s) {
  req.respond({ status: 200, body: "Hello, World!\n" });
}
</code></pre>
<h4>Custom Modules:</h4>
<pre><code class="language-typescript">// my_module.ts
export function add(a: number, b: number): number {
  return a + b;
}

// Import in another file
// import_ts.ts
import { add } from "./my_module.ts";

console.log(add(2, 3)); // Outputs 5
</code></pre>
<h4>JSON Processing in the Standard Library:</h4>
<pre><code class="language-typescript">// json_example.ts
import { readTextFile } from "https://deno.land/std/fs/mod.ts";
import { json as parseJson } from "https://deno.land/std/json/mod.ts";

const jsonData = await readTextFile("data.json");
const data = parseJson(jsonData);
console.log(data);
</code></pre>
<h4>Network Operations in the Standard Library:</h4>
<pre><code class="language-typescript">// net_example.ts
import { connect } from "https://deno.land/std/net/tcp.ts";

const conn = await connect({ hostname: "localhost", port: 8000 });
conn.write(new TextEncoder().encode("GET / HTTP/1.1\r\nHost: localhost:8000\r\n\r\n"));
const response = new TextDecoder().decode(await Deno.readAll(conn));
console.log(response);
conn.close();
</code></pre>
<h4>Using Third-Party Modules from deno.land/x:</h4>
<pre><code class="language-typescript">// third_party_module.ts
import { log } from "https://x.nest.land/log@0.1.0/mod.ts";

log.info("This is an info message");
</code></pre>
<p>Deno’s standard library and third-party modules are typically imported via HTTPS URLs, providing version control and security. <code>deno.land</code> is a module registry similar to npm but designed for Deno. <code>x.nest.land</code> is another Deno module repository hosting community-maintained modules.</p>
<h3>Using WebSocket</h3>
<p>Deno supports WebSocket through its standard library or third-party libraries. The following example uses the <code>ws</code> third-party library, popular for both Deno and Node.js.</p>
<p><strong>Install the</strong> <code>ws</code> <strong>library</strong>:</p>
<pre><code class="language-bash">deno install -A -f --unstable --name deno_ws https://deno.land/x/ws@v1.1.0/mod.ts
</code></pre>
<h4>Server-Side Code</h4>
<p>Create a WebSocket server to listen for client connections and send messages to connected clients.</p>
<pre><code class="language-typescript">// server.ts
import { Server } from "deno_ws/mod.ts";

const server = new Server({ port: 8080 });

server.on("connection", (socket) =&gt; {
  console.log("Client connected");

  socket.on("message", (message) =&gt; {
    console.log(`Received message =&gt; ${message}`);
    socket.send(`You sent -&gt; ${message}`);
  });

  socket.on("close", () =&gt; {
    console.log("Client disconnected");
  });
});

console.log("WebSocket server is running on ws://localhost:8080");
</code></pre>
<h4>Client-Side Code</h4>
<p>Create a WebSocket client to connect to the server and send/receive messages.</p>
<pre><code class="language-typescript">// client.ts
import { connect } from "deno_ws/mod.ts";

const socket = connect("ws://localhost:8080");

socket.on("open", () =&gt; {
  console.log("Connected to WebSocket server");
  socket.send("Hello, Server!");
});

socket.on("message", (message) =&gt; {
  console.log(`Received from server: ${message}`);
});

socket.on("close", () =&gt; {
  console.log("Connection closed");
});
</code></pre>
<h4>Running the Example</h4>
<p>Open two terminal windows.</p>
<p>In the first window, run the server:</p>
<pre><code class="language-bash">deno run --allow-net server.ts
</code></pre>
<p>In the second window, run the client:</p>
<pre><code class="language-bash">deno run --allow-net client.ts
</code></pre>
<p><strong>Server-Side</strong>:</p>
<ul>
<li><p>Imports the <code>Server</code> class and creates an instance listening on port 8080.</p>
</li>
<li><p>Handles new client connections with the <code>connection</code> event, logging and setting up a message handler.</p>
</li>
<li><p>Responds to each received message with a confirmation message.</p>
</li>
<li><p>Logs when a client disconnects via the <code>close</code> event.</p>
</li>
</ul>
<p><strong>Client-Side</strong>:</p>
<ul>
<li><p>Uses the <code>connect</code> function to connect to the server’s URL.</p>
</li>
<li><p>Sets an <code>open</code> event handler to send a message when the connection is established.</p>
</li>
<li><p>Sets a <code>message</code> event handler to receive and log server messages.</p>
</li>
<li><p>Sets a <code>close</code> event handler to log connection closure.</p>
</li>
</ul>
<h3>Error Handling and Debugging</h3>
<h4>Error Handling</h4>
<p>Deno uses <code>try/catch</code> for error handling, supporting asynchronous error handling.</p>
<pre><code class="language-typescript">// error_handling.ts
import { readFile } from "https://deno.land/std/fs/mod.ts";

try {
  const data = await readFile("non_existent_file.txt");
} catch (error) {
  if (error instanceof Deno.errors.NotFound) {
    console.error("File not found:", error);
  } else {
    throw error; // Re-throw unhandled errors
  }
}
</code></pre>
<h4>Debugging</h4>
<p>Debugging in Deno can be done using <code>console.log</code>, <code>console.error</code>, and the <code>debugger</code> statement with an IDE or browser developer tools.</p>
<pre><code class="language-typescript">// debug.ts
function debugFunction(value) {
  debugger; // Pauses execution, allowing context inspection in a debugger
  console.log("Debugging value:", value);
}

debugFunction("Debug me");
</code></pre>
<h3>Performance Optimization</h3>
<ol>
<li><p><strong>Avoid Unnecessary Computations</strong>: Compute values only when needed, avoiding premature calculations.</p>
</li>
<li><p><strong>Use Asynchronous Operations</strong>: For I/O-intensive tasks, use async operations to avoid blocking the main thread.</p>
</li>
<li><p><strong>Cache Results</strong>: Cache results of repetitive computations.</p>
</li>
<li><p><strong>Leverage Type Checking</strong>: TypeScript’s type system helps prevent runtime errors and improves code quality.</p>
</li>
<li><p><strong>Restrict Permissions</strong>: Deno’s permission model allows precise control over code access, minimizing resource waste.</p>
</li>
</ol>
<p>Here’s an optimization example using <code>deno.cache</code> to cache imported modules:</p>
<pre><code class="language-typescript">// optimized_import.ts
import { cache } from "https://deno.land/x/deno.land_std@0.125.0/cache/mod.ts";

const cachedModule = await cache(
  "https://deno.land/x/your_module@latest",
  ".cache",
);

// Import from cache
import * as mod from `${cachedModule}/mod.ts`;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[React Query Efficient API Request and Cache Management]]></title><description><![CDATA[React Query is a powerful state management library designed for handling data fetching, caching, and updating, particularly suited for API interactions. It offers advanced features such as automatic caching, offline state management, data expiration,...]]></description><link>https://tech.tianyaschool.com/react-query-efficient-api-request-and-cache-management</link><guid isPermaLink="true">https://tech.tianyaschool.com/react-query-efficient-api-request-and-cache-management</guid><category><![CDATA[react-query]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 02 Feb 2026 10:53:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zwsHjakE_iI/upload/467f6f10694adc8386edaaabe1955c6c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>React Query is a powerful state management library designed for handling data fetching, caching, and updating, particularly suited for API interactions. It offers advanced features such as automatic caching, offline state management, data expiration, and refetching.</p>
<h3 id="heading-installation">Installation</h3>
<pre><code class="lang-bash">npm install react-query
</code></pre>
<h3 id="heading-importing-and-configuring-react-query">Importing and Configuring React Query</h3>
<p>In your application, you need to import the <code>useQuery</code> Hook and set up a configuration object.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-keyword">const</span> queryClient = <span class="hljs-keyword">new</span> QueryClient();
</code></pre>
<p>Wrap the <code>queryClient</code> around your root component using <code>QueryClientProvider</code> to make it available throughout the application.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { QueryClient, QueryClientProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-keyword">const</span> queryClient = <span class="hljs-keyword">new</span> QueryClient();

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">QueryClientProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{queryClient}</span>&gt;</span>
      {/* Your application */}
    <span class="hljs-tag">&lt;/<span class="hljs-name">QueryClientProvider</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-using-the-usequery-hook">Using the useQuery Hook</h3>
<p>Use <code>useQuery</code> to make API requests and manage response data.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, status, error } = useQuery(<span class="hljs-string">'myQueryKey'</span>, <span class="hljs-function">() =&gt;</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>));

  <span class="hljs-keyword">if</span> (status === <span class="hljs-string">'loading'</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">'Loading...'</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">'An error occurred.'</span>;
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{data}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>Here, <code>myQueryKey</code> is a unique identifier for the query, and <code>fetch('</code><a target="_blank" href="https://api.example.com/data"><code>https://api.example.com/data</code></a><code>')</code> is the actual API call.</p>
<h3 id="heading-configuration-options">Configuration Options</h3>
<p><code>useQuery</code> accepts a configuration object to set caching strategies, retry logic, etc.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { data } = useQuery(
  <span class="hljs-string">'myQueryKey'</span>,
  <span class="hljs-function">() =&gt;</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>),
  {
    <span class="hljs-attr">staleTime</span>: <span class="hljs-number">60000</span>, <span class="hljs-comment">// Time after which data is considered stale and refetched</span>
    <span class="hljs-attr">retry</span>: <span class="hljs-number">3</span>, <span class="hljs-comment">// Number of retries</span>
    <span class="hljs-attr">refetchOnWindowFocus</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Whether to refetch data on window focus</span>
  }
);
</code></pre>
<h3 id="heading-manual-operations">Manual Operations</h3>
<p>You can manually trigger data refetching, cancellation, or error state setting.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { refetch, reset, isFetching } = useQuery(<span class="hljs-string">'myQueryKey'</span>, fetchData);

<span class="hljs-comment">// Refetch data</span>
refetch();

<span class="hljs-comment">// Clear query state and data</span>
reset();

<span class="hljs-comment">// Check if data is being fetched</span>
<span class="hljs-keyword">if</span> (isFetching) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Data is being fetched'</span>);
</code></pre>
<h3 id="heading-subscribing-to-updates">Subscribing to Updates</h3>
<p>You can subscribe to query state changes using the return values of <code>useQuery</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { status, data, error } = useQuery(<span class="hljs-string">'myQueryKey'</span>, fetchData);
useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (status === <span class="hljs-string">'success'</span>) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Data updated:'</span>, data);
}, [status, data]);
</code></pre>
<h3 id="heading-pagination">Pagination</h3>
<p>React Query supports pagination through the <code>useInfiniteQuery</code> Hook for infinite scrolling.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useInfiniteQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyInfiniteList</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, isFetching, hasNextPage, fetchNextPage } = useInfiniteQuery(
    <span class="hljs-string">'myInfiniteQuery'</span>,
    <span class="hljs-keyword">async</span> ({ pageParam = <span class="hljs-number">1</span> }) =&gt; {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://api.example.com/data?page=<span class="hljs-subst">${pageParam}</span>`</span>);
      <span class="hljs-keyword">return</span> response.json();
    },
    {
      <span class="hljs-attr">getNextPageParam</span>: <span class="hljs-function">(<span class="hljs-params">lastPage</span>) =&gt;</span> lastPage.nextPageToken || <span class="hljs-literal">false</span>,
    }
  );

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {data.pages.map((page, index) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>{page.items.map(item =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.title}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>)}<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
      ))}
      {hasNextPage &amp;&amp; !isFetching &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{fetchNextPage}</span>&gt;</span>Load More<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here, <code>getNextPageParam</code> extracts the identifier for the next page from the previous page’s response.</p>
<h3 id="heading-cache-updates">Cache Updates</h3>
<p>When API data is updated, React Query can automatically update the cache, such as during a <code>Mutation</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useMutation } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-keyword">const</span> [updateItem] = useMutation(<span class="hljs-keyword">async</span> (updatedItem) =&gt; {
  <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/items/'</span> + updatedItem.id, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'PUT'</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(updatedItem),
  });
});

<span class="hljs-comment">// Update data and automatically refresh related queries</span>
updateItem.mutate(updatedItem);
</code></pre>
<h3 id="heading-error-handling">Error Handling</h3>
<p>React Query provides built-in error handling mechanisms, allowing you to capture errors via the <code>error</code> property.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { data, error } = useQuery(<span class="hljs-string">'myQueryKey'</span>, fetchData);

<span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error: {error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
</code></pre>
<h3 id="heading-query-cache-cleanup">Query Cache Cleanup</h3>
<p>You can clear the cache for specific queries as needed.</p>
<pre><code class="lang-jsx">queryClient.removeQueries(<span class="hljs-string">'myQueryKey'</span>); <span class="hljs-comment">// Clear all matching queries</span>
queryClient.cancelQueries(<span class="hljs-string">'myQueryKey'</span>); <span class="hljs-comment">// Cancel matching queries</span>
</code></pre>
<h3 id="heading-custom-middleware">Custom Middleware</h3>
<p>You can extend React Query’s functionality with custom middleware, such as adding logging or performance monitoring.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { QueryClient, QueryClientProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-keyword">const</span> queryClient = <span class="hljs-keyword">new</span> QueryClient({
  <span class="hljs-attr">queryCache</span>: <span class="hljs-keyword">new</span> QueryCache({
    <span class="hljs-attr">middlewares</span>: [
      <span class="hljs-comment">// Custom middleware</span>
      myCustomMiddleware,
    ],
  }),
});
</code></pre>
<h3 id="heading-prefetching-data">Prefetching Data</h3>
<p>React Query allows prefetching data before component rendering to improve user experience.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { usePrefetch } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> prefetchData = usePrefetch(<span class="hljs-string">'myQueryKey'</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Prefetch data on component mount</span>
    prefetchData();
  }, []);

  <span class="hljs-comment">// ...other logic</span>
}
</code></pre>
<h3 id="heading-optimistic-updates">Optimistic Updates</h3>
<p>Optimistic updates allow immediate UI updates upon user actions, awaiting server confirmation to provide instant feedback and enhance interaction.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useMutation } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-keyword">const</span> [updateTodo, { optimisticData }] = useMutation(updateTodoMutation, {
  <span class="hljs-attr">onMutate</span>: <span class="hljs-function">(<span class="hljs-params">newTodo</span>) =&gt;</span> {
    <span class="hljs-comment">// Optimistically update client cache</span>
    queryClient.setQueryData([<span class="hljs-string">'todos'</span>, newTodo.id], newTodo);
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">previousTodo</span>: queryClient.getQueryData([<span class="hljs-string">'todos'</span>, newTodo.id]) };
  },
  <span class="hljs-attr">onError</span>: <span class="hljs-function">(<span class="hljs-params">err, newTodo, context</span>) =&gt;</span> {
    <span class="hljs-comment">// Roll back to previous value on error</span>
    queryClient.setQueryData([<span class="hljs-string">'todos'</span>, newTodo.id], context.previousTodo);
  },
  <span class="hljs-attr">onSettled</span>: <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Clean up when query is settled</span>
    queryClient.invalidateQueries(<span class="hljs-string">'todos'</span>);
  },
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleUpdate</span>(<span class="hljs-params">todo</span>) </span>{
  updateTodo({ ...todo, <span class="hljs-attr">completed</span>: !todo.completed });
}
</code></pre>
<h3 id="heading-concurrency-control">Concurrency Control</h3>
<p>Sometimes, you need to control the number of concurrent queries, especially with multiple API calls or high concurrency.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { data } = useQuery([<span class="hljs-string">'concurrentQuery'</span>, { <span class="hljs-attr">limit</span>: <span class="hljs-number">10</span> }], fetchItems, {
  <span class="hljs-attr">staleTime</span>: <span class="hljs-literal">Infinity</span>, <span class="hljs-comment">// Prevent data expiration retries</span>
  <span class="hljs-attr">refetchInterval</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Disable auto-polling</span>
  <span class="hljs-attr">refetchOnWindowFocus</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Disable refetch on window focus</span>
  <span class="hljs-attr">retry</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Do not retry on failure</span>
  <span class="hljs-attr">useErrorBoundary</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// Use error boundaries to prevent component tree crashes</span>
  <span class="hljs-attr">concurrency</span>: <span class="hljs-number">2</span>, <span class="hljs-comment">// Maximum concurrent queries</span>
});
</code></pre>
<h3 id="heading-dependency-injection">Dependency Injection</h3>
<p>If your query logic depends on external parameters, you can use <code>useQueries</code> to execute multiple queries in parallel, each with different configurations.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useQueries } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-query'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params">{ ids }</span>) </span>{
  <span class="hljs-keyword">const</span> queries = useQueries(
    ids.map(<span class="hljs-function"><span class="hljs-params">id</span> =&gt;</span> ({
      <span class="hljs-attr">queryKey</span>: [<span class="hljs-string">'item'</span>, id],
      <span class="hljs-attr">queryFn</span>: <span class="hljs-function">() =&gt;</span> fetchItem(id),
    }))
  );

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {queries.map(query =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{query.queryKey[1]}</span>&gt;</span>
          {query.isLoading ? 'Loading...' : query.data?.title}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>React Query is designed to handle various complex scenarios in modern web applications. With the features above, developers can easily implement data management and state synchronization while maintaining high performance and a great user experience.</p>
]]></content:encoded></item><item><title><![CDATA[TypeScript Advanced Type Techniques Generics, Union, and Intersection Types]]></title><description><![CDATA[Generics
In TypeScript, generics are a powerful tool that allow us to write reusable components capable of adapting to multiple types.
1. Generic Constraints
Generics can be constrained to a specific type or interface, ensuring that the types passed ...]]></description><link>https://tech.tianyaschool.com/typescript-advanced-type-techniques-generics-union-and-intersection-types</link><guid isPermaLink="true">https://tech.tianyaschool.com/typescript-advanced-type-techniques-generics-union-and-intersection-types</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 02 Feb 2026 10:51:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/GnvurwJsKaY/upload/97496584fd4db4763f5d16ced14dd234.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-generics">Generics</h2>
<p>In TypeScript, generics are a powerful tool that allow us to write reusable components capable of adapting to multiple types.</p>
<h3 id="heading-1-generic-constraints">1. Generic Constraints</h3>
<p>Generics can be constrained to a specific type or interface, ensuring that the types passed to the generic meet certain conditions. For example, if we want a function to only accept types with a <code>length</code> property, we can do this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Lengthwise {
  length: <span class="hljs-built_in">number</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printLength</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">Lengthwise</span>&gt;(<span class="hljs-params">item: T</span>): <span class="hljs-title">void</span> </span>{
  <span class="hljs-built_in">console</span>.log(item.length);
}

<span class="hljs-keyword">const</span> stringLength = <span class="hljs-string">"hello"</span>;
printLength(stringLength); <span class="hljs-comment">// OK, strings have a length property</span>
<span class="hljs-keyword">const</span> objectWithoutLength = { name: <span class="hljs-string">"World"</span> };
printLength(objectWithoutLength); <span class="hljs-comment">// Error, no length property</span>
</code></pre>
<p><code>&lt;T extends Lengthwise&gt;</code> ensures that <code>T</code> must have a <code>length</code> property.</p>
<h3 id="heading-2-type-inference-with-generics">2. Type Inference with Generics</h3>
<p>TypeScript allows automatic inference of generic types in certain cases, particularly during function calls. For example, using the <code>infer</code> keyword, we can extract the return type from a function type:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> ReturnType&lt;T&gt; = T <span class="hljs-keyword">extends</span> (...args: <span class="hljs-built_in">any</span>[]) =&gt; infer R ? R : <span class="hljs-built_in">never</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">identity</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}

<span class="hljs-keyword">type</span> IdentityReturnType = ReturnType&lt;<span class="hljs-keyword">typeof</span> identity&gt;; <span class="hljs-comment">// IdentityReturnType is inferred as 'string'</span>
</code></pre>
<p>Here, <code>ReturnType</code> extracts the return type from the function type.</p>
<h3 id="heading-3-multi-parameter-generics">3. Multi-Parameter Generics</h3>
<p>You can define types or functions that accept multiple generic parameters:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Pair&lt;T, U&gt; {
  first: T;
  second: U;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createPair</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">U</span>&gt;(<span class="hljs-params">first: T, second: U</span>): <span class="hljs-title">Pair</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">U</span>&gt; </span>{
  <span class="hljs-keyword">return</span> { first, second };
}

<span class="hljs-keyword">const</span> pair = createPair(<span class="hljs-string">"Hello"</span>, <span class="hljs-number">42</span>); <span class="hljs-comment">// pair has type Pair&lt;string, number&gt;</span>
</code></pre>
<p>The <code>createPair</code> function accepts two generic parameters <code>T</code> and <code>U</code> and returns an object of type <code>Pair&lt;T, U&gt;</code>.</p>
<h3 id="heading-4-generic-interfaces">4. Generic Interfaces</h3>
<p>Interfaces can also use generics:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> GenericIdentityFn&lt;T&gt; {
  (arg: T): T;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">identity</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}

<span class="hljs-keyword">let</span> myIdentity: GenericIdentityFn&lt;<span class="hljs-built_in">number</span>&gt; = identity; <span class="hljs-comment">// myIdentity is a number-specific version of the identity function</span>
</code></pre>
<p>Here, <code>GenericIdentityFn</code> is a generic interface, and the <code>identity</code> function is assigned to an instance of it, restricting it to handle only <code>number</code> type parameters.</p>
<h3 id="heading-5-generic-classes">5. Generic Classes</h3>
<p>Classes can also be defined as generics, allowing methods and properties to use different types:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Box&lt;T&gt; {
  value: T;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">value: T</span>) {
    <span class="hljs-built_in">this</span>.value = value;
  }

  setValue(newValue: T): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.value = newValue;
  }
}

<span class="hljs-keyword">const</span> boxOfStrings = <span class="hljs-keyword">new</span> Box&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">"Hello"</span>);
boxOfStrings.setValue(<span class="hljs-string">"World"</span>); <span class="hljs-comment">// OK</span>
boxOfStrings.setValue(<span class="hljs-number">123</span>); <span class="hljs-comment">// Error, incompatible types</span>
</code></pre>
<p>The <code>Box</code> class accepts a generic type <code>T</code>, and the specific type is specified during instantiation.</p>
<h2 id="heading-union-types">Union Types</h2>
<p>Union types in TypeScript allow combining multiple types into a single type, meaning a variable can be one of several types.</p>
<h3 id="heading-1-type-guards-and-type-assertions">1. Type Guards and Type Assertions</h3>
<p>When dealing with union types, you may need to determine the specific type of a variable. This can be achieved with type guards, which are functions or expressions that check a variable's properties to narrow its possible type range. For example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Shape = { kind: <span class="hljs-string">'circle'</span>; radius: <span class="hljs-built_in">number</span> } | { kind: <span class="hljs-string">'square'</span>; side: <span class="hljs-built_in">number</span> };

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getArea</span>(<span class="hljs-params">shape: Shape</span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-string">'radius'</span> <span class="hljs-keyword">in</span> shape) {
    <span class="hljs-comment">// Type guard: shape is now { kind: 'circle'; radius: number }</span>
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.PI * shape.radius ** <span class="hljs-number">2</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Type guard: shape is now { kind: 'square'; side: number }</span>
    <span class="hljs-keyword">return</span> shape.side ** <span class="hljs-number">2</span>;
  }
}
</code></pre>
<p>In this example, checking if <code>shape</code> has a <code>radius</code> property determines whether it’s a circle or a square.</p>
<h3 id="heading-2-non-null-assertion-operator">2. Non-null Assertion Operator (!)</h3>
<p>The non-null assertion operator <code>!</code> informs the compiler that, even if a union type includes <code>null</code> or <code>undefined</code>, you are certain the value is neither. However, incorrect usage may lead to runtime errors:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logValue</span>(<span class="hljs-params">value: <span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span> | <span class="hljs-literal">undefined</span></span>): <span class="hljs-title">void</span> </span>{
  <span class="hljs-keyword">if</span> (value) {
    <span class="hljs-built_in">console</span>.log(value!.toUpperCase()); <span class="hljs-comment">// Use ! for non-null assertion</span>
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Value is null or undefined'</span>);
  }
}
</code></pre>
<p>Here, if <code>value</code> is not <code>null</code> or <code>undefined</code>, we use <code>!</code> to suppress potential <code>null</code> or <code>undefined</code> type warnings.</p>
<h3 id="heading-3-distributive-type-operator-amp-and">3. Distributive Type Operator (&amp; and |)</h3>
<p>When applying union or intersection types to a generic type, they are distributed across each instance of the generic. For example, with an array whose elements are a union type:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> NumbersOrStrings = <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>;
<span class="hljs-keyword">type</span> ArrayWithMixedElements&lt;T&gt; = T[];

<span class="hljs-keyword">const</span> mixedArray: ArrayWithMixedElements&lt;NumbersOrStrings&gt; = [<span class="hljs-number">1</span>, <span class="hljs-string">"two"</span>, <span class="hljs-number">3</span>];
</code></pre>
<p><code>mixedArray</code>’s element type is <code>NumbersOrStrings</code>, so it can contain <code>number</code> or <code>string</code>.</p>
<h3 id="heading-4-pattern-matching">4. Pattern Matching</h3>
<p>In destructuring assignments, function parameters, or type aliases, pattern matching can be used to handle values of union types:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Shape = { kind: <span class="hljs-string">'circle'</span>; radius: <span class="hljs-built_in">number</span> } | { kind: <span class="hljs-string">'square'</span>; side: <span class="hljs-built_in">number</span> };

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleShape</span>(<span class="hljs-params">shape: Shape</span>) </span>{
  <span class="hljs-keyword">switch</span> (shape.kind) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">'circle'</span>:
      <span class="hljs-keyword">const</span> { radius } = shape;
      <span class="hljs-comment">// Now we know shape is { kind: 'circle'; radius: number }</span>
      <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">case</span> <span class="hljs-string">'square'</span>:
      <span class="hljs-keyword">const</span> { side } = shape;
      <span class="hljs-comment">// Now we know shape is { kind: 'square'; side: number }</span>
      <span class="hljs-keyword">break</span>;
  }
}
</code></pre>
<p>In this example, the <code>switch</code> statement acts as a type guard, handling different shape types based on the <code>kind</code> property.</p>
<h2 id="heading-intersection-types">Intersection Types</h2>
<p>Intersection types in TypeScript allow combining multiple types into a new type that includes all properties and methods of the original types.</p>
<h3 id="heading-1-combining-types">1. Combining Types</h3>
<p>Intersection types use the <code>&amp;</code> operator to merge two or more types. For example, suppose we have two interfaces, <code>Person</code> and <code>Employee</code>. We can create a <code>PersonAndEmployee</code> intersection type:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> Employee {
  id: <span class="hljs-built_in">number</span>;
  department: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">type</span> PersonAndEmployee = Person &amp; Employee;

<span class="hljs-keyword">const</span> person: PersonAndEmployee = {
  name: <span class="hljs-string">'Alice'</span>,
  age: <span class="hljs-number">30</span>,
  id: <span class="hljs-number">123</span>,
  department: <span class="hljs-string">'HR'</span>,
};
</code></pre>
<p>The <code>person</code> variable must satisfy the requirements of both <code>Person</code> and <code>Employee</code> interfaces.</p>
<h3 id="heading-2-intersection-of-classes-and-interfaces">2. Intersection of Classes and Interfaces</h3>
<p>Intersection types can also be applied between classes and interfaces, combining a class instance with the properties and methods of an interface:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Animal {
  name: <span class="hljs-built_in">string</span>;
  makeSound(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Making sound...'</span>);
  }
}

<span class="hljs-keyword">interface</span> HasColor {
  color: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">class</span> ColoredAnimal <span class="hljs-keyword">extends</span> Animal <span class="hljs-keyword">implements</span> HasColor {
  color: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">type</span> ColoredAnimalIntersection = Animal &amp; HasColor;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">describeAnimal</span>(<span class="hljs-params">animal: ColoredAnimalIntersection</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The <span class="hljs-subst">${animal.name}</span> is <span class="hljs-subst">${animal.color}</span> and makes a sound.`</span>);
  animal.makeSound();
}

<span class="hljs-keyword">const</span> coloredCat = <span class="hljs-keyword">new</span> ColoredAnimal();
coloredCat.name = <span class="hljs-string">'Kitty'</span>;
coloredCat.color = <span class="hljs-string">'Gray'</span>;
describeAnimal(coloredCat);
</code></pre>
<p>The <code>ColoredAnimalIntersection</code> type is both an instance of the <code>Animal</code> class and possesses the <code>color</code> property from the <code>HasColor</code> interface.</p>
<h3 id="heading-3-type-guards">3. Type Guards</h3>
<p>Intersection types are useful in type guards, especially when determining a specific type within a union type. For example, you might have an object that could be one of two types, and you want to determine which it is at a specific moment:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Movable {
  move(): <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">interface</span> Static {
  stay(): <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">type</span> ObjectState = Movable &amp; Static;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isMovable</span>(<span class="hljs-params">obj: ObjectState</span>): <span class="hljs-title">obj</span> <span class="hljs-title">is</span> <span class="hljs-title">Movable</span> </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> obj.move === <span class="hljs-string">'function'</span>;
}

<span class="hljs-keyword">const</span> <span class="hljs-built_in">object</span>: ObjectState = {
  move: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Moving...'</span>),
  stay: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Staying...'</span>)
};

<span class="hljs-keyword">if</span> (isMovable(<span class="hljs-built_in">object</span>)) {
  <span class="hljs-built_in">object</span>.move(); <span class="hljs-comment">// Type guard ensures the move method exists</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">object</span>.stay();
}
</code></pre>
<p>The <code>isMovable</code> function is a type guard that checks if the <code>move</code> method exists, confirming that <code>object</code> is of type <code>Movable</code>.</p>
]]></content:encoded></item><item><title><![CDATA[Next.js API Routes Building Server-Side Functionality]]></title><description><![CDATA[Next.js API Routes enable the creation of standalone server-side functionality within a Next.js application, capable of handling HTTP requests and returning JSON data or other responses. API routes reside in the pages/api directory, with each file ma...]]></description><link>https://tech.tianyaschool.com/nextjs-api-routes-building-server-side-functionality</link><guid isPermaLink="true">https://tech.tianyaschool.com/nextjs-api-routes-building-server-side-functionality</guid><category><![CDATA[Next.js]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 02 Feb 2026 10:50:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/vZJdYl5JVXY/upload/50bc1ff980c49276268ead3d7cc4ed5f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Next.js API Routes enable the creation of standalone server-side functionality within a Next.js application, capable of handling HTTP requests and returning JSON data or other responses. API routes reside in the <code>pages/api</code> directory, with each file mapping to a specific API endpoint.</p>
<h2 id="heading-basic-example">Basic Example</h2>
<h3 id="heading-pagesapiusersjs">pages/api/users.js</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> type { NextApiRequest, NextApiResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">'next'</span>;

<span class="hljs-comment">// Get user list</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">'GET'</span>) {
    <span class="hljs-keyword">const</span> users = [
      { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'User 1'</span> },
      { <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'User 2'</span> },
      { <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'User 3'</span> },
    ];

    res.status(<span class="hljs-number">200</span>).json(users);
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">'POST'</span>) {
    <span class="hljs-keyword">const</span> user = req.body;

    <span class="hljs-comment">// Simulate database connection</span>
    <span class="hljs-comment">// await addUserToDatabase(user);</span>

    res.status(<span class="hljs-number">201</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'User added successfully.'</span> });
  } <span class="hljs-keyword">else</span> {
    res.setHeader(<span class="hljs-string">'Allow'</span>, [<span class="hljs-string">'GET'</span>, <span class="hljs-string">'POST'</span>]);
    res.status(<span class="hljs-number">405</span>).end(<span class="hljs-string">`Method <span class="hljs-subst">${req.method}</span> Not Allowed`</span>);
  }
}
</code></pre>
<ol>
<li><p>The <code>pages/api/users.js</code> file defines an API route accessible at <code>/api/users</code>.</p>
</li>
<li><p>The <code>handler</code> function accepts two parameters: <code>req</code> (a <code>NextApiRequest</code> object representing the HTTP request) and <code>res</code> (a <code>NextApiResponse</code> object for the HTTP response).</p>
</li>
<li><p>For GET requests, it returns a user list (hardcoded here, but typically queried from a database in practice).</p>
</li>
<li><p>For POST requests, it accepts user data from the request body, simulates adding it to a database, and returns a success message.</p>
</li>
<li><p>For unsupported methods, it returns a 405 Method Not Allowed error with allowed methods specified.</p>
</li>
</ol>
<blockquote>
<p>Next.js API Routes handle JSON responses by default, but you can return other content types as needed. For example, use <code>res.send</code> to return HTML.</p>
</blockquote>
<h2 id="heading-middleware-and-request-handling-chain">Middleware and Request Handling Chain</h2>
<p>Next.js API Routes support a middleware pattern, allowing preprocessing of requests or post-processing of responses before reaching the final handler. This is useful for validating headers, authentication, logging, etc.</p>
<h3 id="heading-middleware-example">Middleware Example</h3>
<p>To validate an API key for all API requests:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// pages/api/middleware/authenticate.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">authenticate</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse, next: () =&gt; void</span>) </span>{
  <span class="hljs-keyword">const</span> apiKey = req.headers[<span class="hljs-string">'x-api-key'</span>];

  <span class="hljs-keyword">if</span> (!apiKey || apiKey !== process.env.API_KEY) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Unauthorized'</span> });
  }

  next();
}
</code></pre>
<p>Apply the middleware in an API route:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// pages/api/users.js</span>
<span class="hljs-keyword">import</span> { authenticate } <span class="hljs-keyword">from</span> <span class="hljs-string">'./middleware/authenticate'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  authenticate(req, res, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Original logic</span>
  });
}
</code></pre>
<h2 id="heading-error-handling">Error Handling</h2>
<p>Robust error handling is critical for production-grade applications. Next.js API Routes allow custom error handling logic.</p>
<h3 id="heading-error-handling-example">Error Handling Example</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// Code that might throw an error</span>
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> fetchDataFromDatabase();

    res.status(<span class="hljs-number">200</span>).json(result);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error occurred:'</span>, error);
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'An error occurred while processing your request.'</span> });
  }
}
</code></pre>
<h2 id="heading-type-safety">Type Safety</h2>
<p>Using TypeScript for type annotations enhances code robustness and maintainability.</p>
<h3 id="heading-type-safety-example">Type Safety Example</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// pages/api/users.ts</span>
<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { NextApiRequest, NextApiResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">'next'</span>;

<span class="hljs-keyword">type</span> User = {
  id: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse&lt;User[] | { message: <span class="hljs-built_in">string</span> }&gt;</span>) </span>{
  <span class="hljs-comment">// ...</span>
}
</code></pre>
<h2 id="heading-interacting-with-external-services">Interacting with External Services</h2>
<p>Most API routes interact with external services like databases or third-party APIs. Here’s how to use <code>axios</code> for HTTP requests.</p>
<p>Install <code>axios</code>:</p>
<pre><code class="lang-bash">npm install axios
</code></pre>
<p>Use in an API route:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'https://api.example.com/data'</span>);
    res.status(<span class="hljs-number">200</span>).json(response.data);
  } <span class="hljs-keyword">catch</span> (error) {
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Failed to fetch data from external service.'</span> });
  }
}
</code></pre>
<h2 id="heading-custom-and-dynamic-routes">Custom and Dynamic Routes</h2>
<p>Next.js API Routes support more than single paths, allowing complex routing structures, including dynamic routes.</p>
<h3 id="heading-custom-routes">Custom Routes</h3>
<p>To organize related API endpoints, use subdirectories. For a blog API, you might structure it as:</p>
<pre><code class="lang-plaintext">pages/
  api/
    blog/
      posts.ts          # Handles /api/blog/posts requests
      post/[id].ts      # Dynamic route, handles /api/blog/post/:id requests
</code></pre>
<h3 id="heading-dynamic-routes">Dynamic Routes</h3>
<p>Dynamic routes capture URL segments as parameters. In the above example, <code>[id]</code> is a dynamic segment replaced by an actual ID. Access these parameters via <code>req.query</code>.</p>
<h3 id="heading-dynamic-route-example-pagesapiblogpostidts">Dynamic Route Example (pages/api/blog/post/[id].ts)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">const</span> { id } = req.query; <span class="hljs-comment">// Get dynamic ID</span>

  <span class="hljs-keyword">if</span> (!id) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Missing post ID'</span> });
  }

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> getPostById(id <span class="hljs-keyword">as</span> string); <span class="hljs-comment">// Assume this fetches a post from a database</span>
    <span class="hljs-keyword">if</span> (!post) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Post not found'</span> });
    }
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json(post);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error fetching post:'</span>, error);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Internal server error'</span> });
  }
}
</code></pre>
<h2 id="heading-api-route-caching">API Route Caching</h2>
<p>To improve performance, you may want to cache API responses. Next.js doesn’t provide built-in API caching, but you can use client-side libraries like <code>swr</code> or server-side caching with services like Redis.</p>
<h3 id="heading-server-side-caching-example-using-redis">Server-Side Caching Example (Using Redis)</h3>
<p>Install <code>redis</code> and <code>ioredis</code>:</p>
<pre><code class="lang-bash">npm install redis ioredis
</code></pre>
<p>Use Redis to cache data in an API route:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> redis <span class="hljs-keyword">from</span> <span class="hljs-string">'ioredis'</span>;

<span class="hljs-keyword">const</span> redisClient = <span class="hljs-keyword">new</span> redis(process.env.REDIS_URL);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">const</span> { id } = req.query;

  <span class="hljs-keyword">let</span> post;
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// Try fetching from Redis cache</span>
    post = <span class="hljs-keyword">await</span> redisClient.get(<span class="hljs-string">`post:<span class="hljs-subst">${id}</span>`</span>);
    <span class="hljs-keyword">if</span> (post) {
      post = <span class="hljs-built_in">JSON</span>.parse(post);
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json(post);
    }
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Redis error:'</span>, err);
  }

  <span class="hljs-comment">// Fetch from database if not cached</span>
  post = <span class="hljs-keyword">await</span> getPostById(id <span class="hljs-keyword">as</span> string);

  <span class="hljs-keyword">if</span> (post) {
    <span class="hljs-comment">// Store in Redis for future requests</span>
    redisClient.set(<span class="hljs-string">`post:<span class="hljs-subst">${id}</span>`</span>, <span class="hljs-built_in">JSON</span>.stringify(post));
    res.status(<span class="hljs-number">200</span>).json(post);
  } <span class="hljs-keyword">else</span> {
    res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Post not found'</span> });
  }
}
</code></pre>
<h2 id="heading-cors-support">CORS Support</h2>
<p>Cross-Origin Resource Sharing (CORS) is a key aspect of web security. Next.js API Routes support CORS by default, but you can further control CORS policies.</p>
<h3 id="heading-cors-example">CORS Example</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Cors <span class="hljs-keyword">from</span> <span class="hljs-string">'cors'</span>; <span class="hljs-comment">// Install cors library</span>

<span class="hljs-comment">// Initialize CORS middleware</span>
<span class="hljs-keyword">const</span> cors = Cors({
  <span class="hljs-attr">methods</span>: [<span class="hljs-string">'GET'</span>, <span class="hljs-string">'HEAD'</span>],
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-comment">// Apply CORS middleware</span>
  <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    cors(req, res, <span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (result <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span>) {
        reject(result);
      } <span class="hljs-keyword">else</span> {
        resolve(result);
      }
    });
  });

  <span class="hljs-comment">// Subsequent handling logic</span>
}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Web Components and Framework Integration Vue & React Case Study]]></title><description><![CDATA[For a long time, I dreamed of building a fully customizable, reusable, and cross-framework UI component library to streamline my project development. By chance, I discovered Web Components, a native Web API that allows the creation of custom HTML tag...]]></description><link>https://tech.tianyaschool.com/web-components-and-framework-integration-vue-and-react-case-study</link><guid isPermaLink="true">https://tech.tianyaschool.com/web-components-and-framework-integration-vue-and-react-case-study</guid><category><![CDATA[Web Components]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[javascript framework]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Wed, 28 Jan 2026 13:19:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cckf4TsHAuw/upload/befcf2f63e3c923e5e2bec84df529b4a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For a long time, I dreamed of building a fully customizable, reusable, and cross-framework UI component library to streamline my project development. By chance, I discovered Web Components, a native Web API that allows the creation of custom HTML tags for component-based development. Excited by its potential, I decided to integrate Web Components with popular frontend frameworks—React and Vue—in my latest project to explore the possibilities of this combination.</p>
<p>Early in the project, I was captivated by the power of Web Components. Supported natively by browsers, they require no external libraries or frameworks and offer full encapsulation, enabling components to be used independently anywhere.</p>
<h2 id="heading-web-components-integration-with-vue">Web Components Integration with Vue</h2>
<p>Integrating Web Components with Vue.js typically involves creating and using custom elements within a Vue application while preserving Vue’s data binding and lifecycle methods.</p>
<h3 id="heading-installing-vueweb-component-wrapper">Installing @vue/web-component-wrapper</h3>
<pre><code class="lang-bash">npm install --save @vue/web-component-wrapper
</code></pre>
<p>Suppose we have a Vue component named <code>MyVueComponent.vue</code>:</p>
<h3 id="heading-myvuecomponentvue">MyVueComponent.vue</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ message }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"increment"</span>&gt;</span>Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  data() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello from Vue Component'</span>
    };
  },
  <span class="hljs-attr">methods</span>: {
    increment() {
      <span class="hljs-built_in">this</span>.message = <span class="hljs-string">'Count incremented!'</span>;
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Next, we can use <code>@vue/web-component-wrapper</code> to convert this Vue component into a Web Component:</p>
<h3 id="heading-indexjs">index.js</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;
<span class="hljs-keyword">import</span> MyVueComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./MyVueComponent.vue'</span>;
<span class="hljs-keyword">import</span> VueWebComponentWrapper <span class="hljs-keyword">from</span> <span class="hljs-string">'@vue/web-component-wrapper'</span>;

Vue.customElement(<span class="hljs-string">'my-vue-component'</span>, MyVueComponent);

<span class="hljs-comment">// Alternatively, if you want to use LitElement as a base:</span>
<span class="hljs-comment">// import { LitElement, html } from 'lit-element';</span>
<span class="hljs-comment">// import { wrap } from '@vue/web-component-wrapper';</span>
<span class="hljs-comment">// import MyVueComponent from './MyVueComponent.vue';</span>

<span class="hljs-comment">// class MyCustomElement extends LitElement {</span>
<span class="hljs-comment">//   render() {</span>
<span class="hljs-comment">//     return html`</span>
<span class="hljs-comment">//       &lt;my-vue-component&gt;&lt;/my-vue-component&gt;</span>
<span class="hljs-comment">//     `;</span>
<span class="hljs-comment">//   }</span>
<span class="hljs-comment">// }</span>

<span class="hljs-comment">// wrap(Vue, MyCustomElement, MyVueComponent);</span>

customElements.define(<span class="hljs-string">'my-vue-component'</span>, VueWebComponentWrapper(MyVueComponent));
</code></pre>
<p>Now, you can use the <code>&lt;my-vue-component&gt;</code> tag anywhere Web Components are supported, like this:</p>
<h3 id="heading-indexhtml">index.html</h3>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Vue Web Component<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">my-vue-component</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">my-vue-component</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The Vue component <code>MyVueComponent</code> is transformed into a Web Component, retaining its internal data binding and methods. In an external HTML file, you can use the <code>&lt;my-vue-component&gt;</code> tag without importing the entire Vue library.</p>
<h3 id="heading-vue-page-appvue">Vue Page (App.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">my-vue-component</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">my-vue-component</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-web-components-integration-with-react">Web Components Integration with React</h2>
<p>Web Components can be used directly in React applications since they are natively supported by browsers, independent of specific frameworks.</p>
<h3 id="heading-web-component-mycustomelementjs">Web Component (MyCustomElement.js)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { LitElement, html, css } <span class="hljs-keyword">from</span> <span class="hljs-string">'lit-element'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomElement</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">LitElement</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span> <span class="hljs-title">styles</span>() {
    <span class="hljs-keyword">return</span> css`<span class="css">
      <span class="hljs-comment">/* Custom styles */</span>
    `</span>;
  }

  <span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span> <span class="hljs-title">properties</span>() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">someProp</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span> },
    };
  }

  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.someProp = <span class="hljs-string">'Default value'</span>;
  }

  _handleClick() {
    <span class="hljs-built_in">this</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'custom-event'</span>, { <span class="hljs-attr">detail</span>: <span class="hljs-string">'Hello from LitElement'</span> }));
  }

  render() {
    <span class="hljs-keyword">return</span> html`<span class="xml">
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"</span></span></span><span class="hljs-subst">${<span class="hljs-built_in">this</span>._handleClick}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span></span><span class="hljs-subst">${<span class="hljs-built_in">this</span>.someProp}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    `</span>;
  }
}

customElements.define(<span class="hljs-string">'my-custom-element'</span>, MyCustomElement);
</code></pre>
<h3 id="heading-react-component-appjs">React Component (App.js)</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> handleCustomEvent = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Custom event received:'</span>, event.detail);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">my-custom-element</span> <span class="hljs-attr">some-prop</span>=<span class="hljs-string">"React Value"</span> <span class="hljs-attr">on-custom-event</span>=<span class="hljs-string">{handleCustomEvent}</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">my-custom-element</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h3 id="heading-key-considerations-for-using-web-components-in-react">Key Considerations for Using Web Components in React</h3>
<ul>
<li><p><strong>Property Binding</strong>: React uses camelCase for properties, while Web Components use kebab-case. In React, use <code>some-prop</code> instead of <code>someProp</code> for attribute binding.</p>
</li>
<li><p><strong>Event Listening</strong>: React’s JSX <code>@event</code> syntax doesn’t directly map to Web Component event listeners. React attaches event listeners to the outermost DOM element, so <code>@custom-event</code> listens on the React component’s root, not directly on the Web Component. If the Web Component’s events don’t bubble, handle them within the Web Component itself.</p>
</li>
<li><p><strong>State Management and Updates</strong>: React’s state management and component update mechanisms differ from Web Components. Web Component state changes won’t trigger React re-renders.</p>
</li>
<li><p><strong>Lifecycle Methods</strong>: React’s lifecycle methods don’t fully align with Web Components’ lifecycles. Coordination may be needed for operations tied to specific lifecycle stages.</p>
</li>
<li><p><strong>Performance Considerations</strong>: Since React doesn’t directly manage Web Components, additional optimizations like <code>shouldComponentUpdate</code> or <code>React.memo</code> may be required to minimize unnecessary renders.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Frontend Error Monitoring and Log Collection Practices]]></title><description><![CDATA[Frontend error monitoring and log collection are critical for ensuring application stability and enhancing user experience. This document explores commonly used methods for frontend error monitoring and log collection.
Using try-catch for Error Handl...]]></description><link>https://tech.tianyaschool.com/frontend-error-monitoring-and-log-collection-practices</link><guid isPermaLink="true">https://tech.tianyaschool.com/frontend-error-monitoring-and-log-collection-practices</guid><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Wed, 28 Jan 2026 13:12:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/jLwVAUtLOAQ/upload/8afd5cba1942dc1b9cb60512bf77b60d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Frontend error monitoring and log collection are critical for ensuring application stability and enhancing user experience. This document explores commonly used methods for frontend error monitoring and log collection.</p>
<h2 id="heading-using-try-catch-for-error-handling">Using try-catch for Error Handling</h2>
<p>Wrap potentially error-prone code in a <code>try-catch</code> block to capture errors:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">try</span> {
  <span class="hljs-comment">// Code that might throw an error</span>
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-comment">// Handle the caught error</span>
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'An error occurred:'</span>, error);
  <span class="hljs-comment">// Report error to backend logging service</span>
  reportErrorToBackend(error);
}
</code></pre>
<p>In the <code>reportErrorToBackend</code> function, use libraries like <code>fetch</code> or <code>axios</code> to send error details to the server.</p>
<h2 id="heading-using-the-browsers-windowonerror-event">Using the Browser’s window.onerror Event</h2>
<p>A global error handler can capture uncaught errors:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">window</span>.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">errorMessage, fileName, lineNumber, columnNumber, error</span>) </span>{
  <span class="hljs-comment">// Log error details</span>
  <span class="hljs-built_in">console</span>.error(errorMessage, fileName, lineNumber, columnNumber, error);
  <span class="hljs-comment">// Send to backend</span>
  reportErrorToBackend(errorMessage, fileName, lineNumber, columnNumber, error);
  <span class="hljs-comment">// Return true to prevent default browser behavior</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
</code></pre>
<h2 id="heading-using-third-party-libraries-like-trackjs">Using Third-Party Libraries like TrackJS</h2>
<p>TrackJS provides an automated way to collect and analyze errors:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.trackjs.com/track.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
TrackJS.configure({
  <span class="hljs-attr">token</span>: <span class="hljs-string">'your_token_here'</span>,
  <span class="hljs-attr">application</span>: <span class="hljs-string">'your_application_name'</span>,
});
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-using-error-boundary-in-react">Using Error Boundary in React</h2>
<p>For React applications, Error Boundaries can capture and handle errors within components:</p>
<pre><code class="lang-jsx"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ErrorBoundary</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = { <span class="hljs-attr">hasError</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">errorInfo</span>: <span class="hljs-literal">null</span> };
  }

  <span class="hljs-keyword">static</span> getDerivedStateFromError(error) {
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">hasError</span>: <span class="hljs-literal">true</span> };
  }

  componentDidCatch(error, errorInfo) {
    <span class="hljs-comment">// Log error</span>
    reportErrorToBackend(error, errorInfo);
  }

  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.state.hasError) {
      <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Something went wrong.<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.props.children; <span class="hljs-comment">// Normally, re-render children</span>
  }
}

<span class="hljs-comment">// Wrap potentially error-prone components</span>
&lt;ErrorBoundary&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">MyComponentThatMayThrow</span> /&gt;</span></span>
&lt;/ErrorBoundary&gt;
</code></pre>
<h2 id="heading-using-vuejs-error-handling">Using Vue.js Error Handling</h2>
<p>Vue.js supports both global and component-level error handling:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Global error handling</span>
Vue.config.errorHandler = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error, instance, info</span>) </span>{
  <span class="hljs-built_in">console</span>.error(error, instance, info);
  reportErrorToBackend(error, info);
};

<span class="hljs-comment">// Component-level error handling</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  created() {
    <span class="hljs-built_in">this</span>.$onErrorCapture = <span class="hljs-function">(<span class="hljs-params">error, instance, info</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.error(error, instance, info);
      reportErrorToBackend(error, info);
    };
  },
};
</code></pre>
<h2 id="heading-using-angulars-errorhandler">Using Angular’s ErrorHandler</h2>
<p>Angular provides an <code>ErrorHandler</code> service for global error handling:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { ErrorHandler, Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CustomErrorHandler <span class="hljs-keyword">implements</span> ErrorHandler {
  handleError(error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'An error occurred:'</span>, error);
    reportErrorToBackend(error);
  }
}
</code></pre>
<p><strong>Register the error handler in AppModule:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-meta">@NgModule</span>({
  providers: [{ provide: ErrorHandler, useClass: CustomErrorHandler }],
  <span class="hljs-comment">// ...</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule {}
</code></pre>
<h2 id="heading-using-sentry">Using Sentry</h2>
<p>Sentry is a popular error tracking service offering detailed error reports, context, and stack traces:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://browser.sentry-cdn.com/5.16.4/minimal@sentry.io/dist/sentry.min.js"</span>
  <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
Sentry.init({
  <span class="hljs-attr">dsn</span>: <span class="hljs-string">'your_sentry_dsn'</span>,
  <span class="hljs-attr">release</span>: <span class="hljs-string">'your_app@version'</span>,
  <span class="hljs-attr">integrations</span>: [<span class="hljs-keyword">new</span> Sentry.Integrations.BrowserTracing()],
  <span class="hljs-attr">tracesSampleRate</span>: <span class="hljs-number">0.5</span>, <span class="hljs-comment">// Adjust sampling rate</span>
});
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-using-logrocket">Using LogRocket</h2>
<p>LogRocket provides user session recording and error tracking:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
!<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">LR</span>)</span>{<span class="hljs-keyword">var</span> t;t=<span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"script"</span>),
t.setAttribute(<span class="hljs-string">"src"</span>,<span class="hljs-string">"https://logs-01.logrocket.io/ln.js?projectid=your_project_id"</span>),
t.setAttribute(<span class="hljs-string">"data-logrocket"</span>,<span class="hljs-string">"true"</span>),t.setAttribute(<span class="hljs-string">"async"</span>,<span class="hljs-string">"true"</span>),
<span class="hljs-built_in">document</span>.body.appendChild(t)}();
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-using-loggly">Using Loggly</h2>
<p>Loggly is a cloud-based log management service:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://js.loggly.com/inputs/your_loggly_key.js"</span> <span class="hljs-attr">async</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
logglyTracker.push([<span class="hljs-string">'log'</span>, <span class="hljs-string">'An error occurred'</span>, { <span class="hljs-attr">error</span>: errorObject }]);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-local-log-files">Local Log Files</h2>
<p>You can log errors locally and periodically upload them to a server, useful in offline environments or when avoiding real-time reporting:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">writeLocalLogFile</span>(<span class="hljs-params">error</span>) </span>{
  <span class="hljs-keyword">const</span> timestamp = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString();
  <span class="hljs-keyword">const</span> logEntry = <span class="hljs-string">`<span class="hljs-subst">${timestamp}</span>: <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(error)}</span>`</span>;
  <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'errorLog'</span>, (<span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'errorLog'</span>) || <span class="hljs-string">''</span>) + <span class="hljs-string">'\n'</span> + logEntry);
}

<span class="hljs-comment">// Usage</span>
<span class="hljs-keyword">try</span> {
  <span class="hljs-comment">// Your code</span>
} <span class="hljs-keyword">catch</span> (error) {
  writeLocalLogFile(error);
  reportErrorToBackend(error); <span class="hljs-comment">// If network available, send</span>
}
</code></pre>
<h2 id="heading-client-side-error-reporting">Client-Side Error Reporting</h2>
<p>Enhance user experience by adding a feedback mechanism, allowing users to choose whether to report errors:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showReportErrorDialog</span>(<span class="hljs-params">error</span>) </span>{
  <span class="hljs-keyword">const</span> dialogResult = confirm(<span class="hljs-string">'Do you want to report this error?'</span>);
  <span class="hljs-keyword">if</span> (dialogResult) {
    reportErrorToBackend(error);
  }
}

<span class="hljs-keyword">try</span> {
  <span class="hljs-comment">// Your code</span>
} <span class="hljs-keyword">catch</span> (error) {
  showReportErrorDialog(error);
}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Deep Dive into Vue.js Component Communication Methods]]></title><description><![CDATA[Vue.js component communication is achieved through several methods, each suited to specific use cases. Below is a comprehensive overview of these methods, including code examples and their characteristics.
Props

Direction: Parent to Child

Purpose: ...]]></description><link>https://tech.tianyaschool.com/deep-dive-into-vuejs-component-communication-methods</link><guid isPermaLink="true">https://tech.tianyaschool.com/deep-dive-into-vuejs-component-communication-methods</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Wed, 28 Jan 2026 13:07:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ylveRpZ8L1s/upload/d5d3134d84e8f538ec74a51aae8ffc3a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Vue.js component communication is achieved through several methods, each suited to specific use cases. Below is a comprehensive overview of these methods, including code examples and their characteristics.</p>
<h2 id="heading-props">Props</h2>
<ul>
<li><p><strong>Direction</strong>: Parent to Child</p>
</li>
<li><p><strong>Purpose</strong>: Allows a parent component to pass data to a child component via attributes.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Read-Only</strong>: Props are immutable by default in the child component.</p>
</li>
<li><p><strong>Validation</strong>: Props can have defined validation rules.</p>
</li>
<li><p><strong>Dynamic</strong>: Props can update with changes in the parent component’s state.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-parent-component-parentvue">Parent Component (Parent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">:message</span>=<span class="hljs-string">"parentMessage"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> ChildComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./ChildComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    ChildComponent
  },
  data() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">parentMessage</span>: <span class="hljs-string">'Hello from Parent'</span>
    };
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-child-component-childcomponentvue">Child Component (ChildComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ message }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">props</span>: {
    <span class="hljs-attr">message</span>: <span class="hljs-built_in">String</span>
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-emit-events">$emit (Events)</h2>
<ul>
<li><p><strong>Direction</strong>: Child to Parent</p>
</li>
<li><p><strong>Purpose</strong>: Enables a child component to notify the parent by triggering custom events.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Data Transmission</strong>: Events can carry data payloads.</p>
</li>
<li><p><strong>Multiple Events</strong>: A child can emit multiple distinct events.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-child-component-childcomponentvue-1">Child Component (ChildComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"notifyParent"</span>&gt;</span>Notify Parent<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">methods</span>: {
    notifyParent() {
      <span class="hljs-built_in">this</span>.$emit(<span class="hljs-string">'child-event'</span>, <span class="hljs-string">'Hello from Child'</span>);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-parent-component-parentvue-1">Parent Component (Parent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> @<span class="hljs-attr">child-event</span>=<span class="hljs-string">"handleChildEvent"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> ChildComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./ChildComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    ChildComponent
  },
  <span class="hljs-attr">methods</span>: {
    handleChildEvent(data) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Received data from child:'</span>, data);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-vuex">Vuex</h2>
<ul>
<li><p><strong>Global State Management</strong></p>
</li>
<li><p><strong>Purpose</strong>: Manages application-wide state accessible by any component.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>State</strong>: Stores global state data.</p>
</li>
<li><p><strong>Mutations</strong>: Synchronous operations, the only way to modify state.</p>
</li>
<li><p><strong>Actions</strong>: Handle asynchronous operations, dispatching mutations.</p>
</li>
<li><p><strong>Getters</strong>: Computed properties based on state, cached for efficiency.</p>
</li>
<li><p><strong>Modules</strong>: Split state management into modules for large applications.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-setting-up-vuex-store-storejs">Setting Up Vuex Store (store.js)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;
<span class="hljs-keyword">import</span> Vuex <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span>;

Vue.use(Vuex);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">new</span> Vuex.Store({
  <span class="hljs-attr">state</span>: {
    <span class="hljs-attr">sharedCounter</span>: <span class="hljs-number">0</span>
  },
  <span class="hljs-attr">mutations</span>: {
    increment(state) {
      state.sharedCounter++;
    }
  },
  <span class="hljs-attr">actions</span>: {
    incrementAsync({ commit }) {
      <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
        commit(<span class="hljs-string">'increment'</span>);
      }, <span class="hljs-number">1000</span>);
    }
  },
  <span class="hljs-attr">getters</span>: {
    <span class="hljs-attr">getCounter</span>: <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> state.sharedCounter
  }
});
</code></pre>
<h3 id="heading-main-application-mainjs">Main Application (main.js)</h3>
<p>Ensure the application integrates the Vuex Store:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">'./store'</span>;

<span class="hljs-keyword">new</span> Vue({
  store,
  <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> h(App)
}).$mount(<span class="hljs-string">'#app'</span>);
</code></pre>
<h3 id="heading-using-vuex-in-components-componentusingvuexvue">Using Vuex in Components (ComponentUsingVuex.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Counter: {{ counter }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"increment"</span>&gt;</span>Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"incrementAsync"</span>&gt;</span>Increment Async<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">computed</span>: {
    counter() {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.$store.getters.getCounter;
    }
  },
  <span class="hljs-attr">methods</span>: {
    increment() {
      <span class="hljs-built_in">this</span>.$store.commit(<span class="hljs-string">'increment'</span>);
    },
    incrementAsync() {
      <span class="hljs-built_in">this</span>.$store.dispatch(<span class="hljs-string">'incrementAsync'</span>);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-provideinject">Provide/Inject</h2>
<ul>
<li><p><strong>Cross-Level Communication</strong></p>
</li>
<li><p><strong>Purpose</strong>: Allows an ancestor component to provide data that descendants can inject, bypassing intermediate parent-child hierarchies.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Hierarchy-Independent</strong>: Works across multiple levels but may increase code coupling.</p>
</li>
<li><p><strong>Limited Use</strong>: Best suited for library or framework-level data passing, not general component communication.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-ancestor-component-ancestorcomponentvue">Ancestor Component (AncestorComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  provide() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">ancestorValue</span>: <span class="hljs-string">'Value from Ancestor'</span>
    };
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-descendant-component-descendantcomponentvue">Descendant Component (DescendantComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Value from Ancestor: {{ ancestorValue }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">inject</span>: [<span class="hljs-string">'ancestorValue'</span>],
  mounted() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Injected value:'</span>, <span class="hljs-built_in">this</span>.ancestorValue);
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-ref-and-v-model">Ref and v-model</h2>
<ul>
<li><p><strong>Direct Reference</strong></p>
</li>
<li><p><strong>Purpose</strong>: Allows a parent to directly access a child component instance or enable two-way data binding.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Refs</strong>: Used to access child component instances or DOM elements for direct manipulation.</p>
</li>
<li><p><strong>v-model</strong>: Facilitates two-way data binding, commonly used with form elements or custom components.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-parent-component-parentcomponentvue">Parent Component (ParentComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"childRef"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"parentValue"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"logChildRef"</span>&gt;</span>Log Child Ref<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> ChildComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./ChildComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    ChildComponent
  },
  data() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">parentValue</span>: <span class="hljs-string">'Initial Value'</span>
    };
  },
  <span class="hljs-attr">methods</span>: {
    logChildRef() {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.$refs.childRef);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-child-component-childcomponentvue-2">Child Component (ChildComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">:value</span>=<span class="hljs-string">"value"</span> @<span class="hljs-attr">input</span>=<span class="hljs-string">"$emit('input', $event.target.value)"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">props</span>: [<span class="hljs-string">'value'</span>]
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-custom-events">Custom Events</h2>
<ul>
<li><p><strong>Event-Based Communication</strong></p>
</li>
<li><p><strong>Purpose</strong>: Enables non-standard communication between components via custom events.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Flexible</strong>: Can be triggered and listened to between any components.</p>
</li>
<li><p><strong>Complex Interactions</strong>: Suitable for specific interactions or intricate component communication.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-child-component-childcomponentvue-3">Child Component (ChildComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"customEvent"</span>&gt;</span>Send Custom Event<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">methods</span>: {
    customEvent() {
      <span class="hljs-built_in">this</span>.$emit(<span class="hljs-string">'custom-event'</span>, <span class="hljs-string">'Data to send'</span>);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-parent-component-parentcomponentvue-1">Parent Component (ParentComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> @<span class="hljs-attr">custom-event</span>=<span class="hljs-string">"handleCustomEvent"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> ChildComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./ChildComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    ChildComponent
  },
  <span class="hljs-attr">methods</span>: {
    handleCustomEvent(data) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Received custom event data:'</span>, data);
    }
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-slots">Slots</h2>
<ul>
<li><p><strong>Content Distribution</strong></p>
</li>
<li><p><strong>Purpose</strong>: Allows a parent component to insert content into specific areas of a child component.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><strong>Default Slot</strong>: The default content area in a child component.</p>
</li>
<li><p><strong>Named Slots</strong>: Multiple slots can be defined, with the parent specifying content placement.</p>
</li>
<li><p><strong>Scoped Slots</strong>: The parent can access child component data to customize slot content.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-parent-component-parentcomponentvue-2">Parent Component (ParentComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">WrapperComponent</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"header"</span>&gt;</span>Custom Header<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"body"</span>&gt;</span>Custom Body Content<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">WrapperComponent</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> WrapperComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./WrapperComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    WrapperComponent
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-wrapper-component-wrappercomponentvue">Wrapper Component (WrapperComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"header"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"content"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"body"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
</code></pre>
<h2 id="heading-composition-api">Composition API</h2>
<ul>
<li><p><strong>New Feature</strong></p>
</li>
<li><p><strong>Purpose</strong>: Introduced in Vue 3, it provides better logic and data organization within components.</p>
</li>
<li><p><strong>Characteristics</strong>:</p>
<ul>
<li><p><code>setup()</code> Function: Runs at the start of the component lifecycle, accessing props and lifecycle hooks.</p>
</li>
<li><p><code>ref</code> and <code>reactive</code>: Manage reactive data.</p>
</li>
<li><p><code>provide</code> and <code>inject</code>: Enhanced implementations for flexible cross-component data passing.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-parent-component-parentcomponentvue-3">Parent Component (ParentComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">:count</span>=<span class="hljs-string">"count"</span> @<span class="hljs-attr">updateCount</span>=<span class="hljs-string">"updateCount"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> { ref, onMounted } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;
<span class="hljs-keyword">import</span> ChildComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./ChildComponent.vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">components</span>: {
    ChildComponent
  },
  setup() {
    <span class="hljs-keyword">const</span> count = ref(<span class="hljs-number">0</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateCount</span>(<span class="hljs-params">newCount</span>) </span>{
      count.value = newCount;
    }

    onMounted(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Initial count:'</span>, count.value);
    });

    <span class="hljs-keyword">return</span> {
      count,
      updateCount
    };
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-child-component-childcomponentvue-4">Child Component (ChildComponent.vue)</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"increment"</span>&gt;</span>Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> { ref } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">props</span>: [<span class="hljs-string">'count'</span>],
  setup(props, { emit }) {
    <span class="hljs-keyword">const</span> count = ref(props.count);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
      count.value++;
      emit(<span class="hljs-string">'updateCount'</span>, count.value);
    }

    <span class="hljs-keyword">return</span> {
      count,
      increment
    };
  }
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Webpack Performance Tuning-Comprehensive Optimization from Loaders to Plugins]]></title><description><![CDATA[Webpack is a module bundler that transforms project resources (JavaScript, CSS, images, etc.) into one or more browser-compatible output files. Optimizing Webpack performance focuses on reducing build time, minimizing output file size, and improving ...]]></description><link>https://tech.tianyaschool.com/webpack-performance-tuning-comprehensive-optimization-from-loaders-to-plugins</link><guid isPermaLink="true">https://tech.tianyaschool.com/webpack-performance-tuning-comprehensive-optimization-from-loaders-to-plugins</guid><category><![CDATA[webpack]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Thu, 22 Jan 2026 14:30:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/hGV2TfOh0ns/upload/e0f7163f1708d5e4776d8092c9ed76c8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Webpack is a module bundler that transforms project resources (JavaScript, CSS, images, etc.) into one or more browser-compatible output files. Optimizing Webpack performance focuses on reducing build time, minimizing output file size, and improving application load speed.</p>
<h2 id="heading-code-splitting">Code Splitting</h2>
<p>Use dynamic <code>import()</code> or <code>webpack.optimize.SplitChunksPlugin</code> to split code, separating infrequently used modules or libraries into distinct chunks loaded only when needed, reducing initial load time.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Dynamic import example</span>
<span class="hljs-keyword">let</span> <span class="hljs-built_in">module</span> = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./module.js'</span>);
</code></pre>
<h2 id="heading-tree-shaking">Tree Shaking</h2>
<p>Webpack 4 and above support tree shaking for ES6 modules, removing unused code via static analysis. Use <code>import</code> instead of <code>require</code> and avoid side-effect imports.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Hinders tree shaking</span>
<span class="hljs-keyword">var</span> _unusedFunction = <span class="hljs-built_in">require</span>(<span class="hljs-string">'library'</span>).unusedFunction;

<span class="hljs-comment">// Supports tree shaking</span>
<span class="hljs-keyword">import</span> { usedFunction } <span class="hljs-keyword">from</span> <span class="hljs-string">'library'</span>;
</code></pre>
<h2 id="heading-lazy-loading">Lazy Loading</h2>
<p>For large single-page applications, lazy-load components to load them only when users navigate to the corresponding route.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Lazy loading with React Router</span>
<span class="hljs-keyword">import</span> React, { lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">const</span> LazyComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./LazyComponent'</span>));

<span class="hljs-comment">// In route configuration</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/lazy"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{LazyComponent}</span> /&gt;</span></span>
</code></pre>
<h2 id="heading-minification-amp-obfuscation">Minification &amp; Obfuscation</h2>
<p>Use UglifyJS or Terser plugins to compress and obfuscate code, reducing output file size.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> TerserPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'terser-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">minimize</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">minimizer</span>: [<span class="hljs-keyword">new</span> TerserPlugin()],
  },
};
</code></pre>
<h2 id="heading-declaration-files">Declaration Files</h2>
<p>Provide type declaration files for TypeScript libraries to enable Webpack type checking and optimization.</p>
<h2 id="heading-module-resolution">Module Resolution</h2>
<p>Optimize module resolution rules to reduce module lookup time.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">resolve</span>: {
    <span class="hljs-attr">extensions</span>: [<span class="hljs-string">'.js'</span>, <span class="hljs-string">'.jsx'</span>, <span class="hljs-string">'.ts'</span>, <span class="hljs-string">'.tsx'</span>],
    <span class="hljs-attr">alias</span>: {
      <span class="hljs-string">'@components'</span>: path.resolve(__dirname, <span class="hljs-string">'src/components'</span>),
    },
  },
};
</code></pre>
<h2 id="heading-caching">Caching</h2>
<p>Use <code>hard-source-webpack-plugin</code> or <code>cache-loader</code> to cache compilation results, speeding up subsequent builds.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> HardSourceWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'hard-source-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HardSourceWebpackPlugin(),
  ],
};
</code></pre>
<h2 id="heading-image-and-font-icon-handling">Image and Font Icon Handling</h2>
<p>Use <code>url-loader</code> or <code>file-loader</code> to process images and font icons, inlining small files into CSS or JavaScript and bundling larger files separately.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|jpg|gif)$/</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'url-loader'</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">limit</span>: <span class="hljs-number">8192</span>, <span class="hljs-comment">// Base64 encode images smaller than 8KB</span>
            },
          },
        ],
      },
    ],
  },
};
</code></pre>
<h2 id="heading-source-maps">Source Maps</h2>
<p>Enable source maps in development (<code>devtool: 'source-map'</code>) for debugging. In production, use a more efficient type like <code>'cheap-module-source-map'</code> to reduce bundle size.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">devtool</span>: process.env.NODE_ENV === <span class="hljs-string">'production'</span> ? <span class="hljs-string">'cheap-module-source-map'</span> : <span class="hljs-string">'source-map'</span>,
};
</code></pre>
<h2 id="heading-deduplication">Deduplication</h2>
<p>Use <code>terser-webpack-plugin</code>’s <code>terserOptions</code> to remove duplicate modules (replacing the deprecated <code>webpack.DedupePlugin</code> in Webpack 4).</p>
<h2 id="heading-css-and-svg-optimization">CSS and SVG Optimization</h2>
<p>Extract CSS into separate files with <code>mini-css-extract-plugin</code> for caching. Preprocess CSS (e.g., SCSS, LESS) and post-process with tools like Autoprefixer. Optimize SVG icons using <code>svg-sprite-loader</code> or <code>svg-url-loader</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mini-css-extract-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
        use: [MiniCssExtractPlugin.loader, <span class="hljs-string">'css-loader'</span>, <span class="hljs-string">'sass-loader'</span>],
      },
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.svg$/</span>,
        use: [<span class="hljs-string">'svg-url-loader'</span>],
      },
    ],
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> MiniCssExtractPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].css'</span>,
      <span class="hljs-attr">chunkFilename</span>: <span class="hljs-string">'[id].css'</span>,
    }),
  ],
};
</code></pre>
<h2 id="heading-preloading-amp-prefetching">Preloading &amp; Prefetching</h2>
<p>Use HTML <code>&lt;link rel="preload"&gt;</code> and <code>&lt;link rel="prefetch"&gt;</code> tags to load resources in advance.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"preload"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/fonts/my-font.woff2"</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"font"</span> <span class="hljs-attr">crossorigin</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"prefetch"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/images/large-image.jpg"</span>&gt;</span>
</code></pre>
<h2 id="heading-parallel-processing">Parallel Processing</h2>
<p>Use <code>thread-loader</code> or <code>worker-loader</code> to leverage multi-core processors for parallel task processing.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
        enforce: <span class="hljs-string">'pre'</span>,
        <span class="hljs-attr">use</span>: <span class="hljs-string">'thread-loader'</span>,
      },
    ],
  },
};
</code></pre>
<h2 id="heading-custom-webpack-devserver">Custom Webpack DevServer</h2>
<p>Customize <code>webpack-dev-server</code> settings, such as enabling Hot Module Replacement (HMR) or configuring proxies.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">hot</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">proxy</span>: {
      <span class="hljs-string">'/api'</span>: {
        <span class="hljs-attr">target</span>: <span class="hljs-string">'http://api.example.com'</span>,
        <span class="hljs-attr">secure</span>: <span class="hljs-literal">false</span>,
      },
    },
  },
};
</code></pre>
<h2 id="heading-optimizing-external-dependencies">Optimizing External Dependencies</h2>
<p>Treat third-party libraries as external dependencies to avoid redundant bundling, using the <code>externals</code> configuration.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">externals</span>: {
    <span class="hljs-attr">react</span>: <span class="hljs-string">'React'</span>,
    <span class="hljs-string">'react-dom'</span>: <span class="hljs-string">'ReactDOM'</span>,
  },
};
</code></pre>
<h2 id="heading-common-chunks">Common Chunks</h2>
<p>Extract shared modules with <code>SplitChunksPlugin</code> (replacing <code>CommonsChunkPlugin</code> in Webpack 4) to reduce duplicate code and speed up page loads.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">runtimeChunk</span>: <span class="hljs-string">'single'</span>,
    <span class="hljs-attr">splitChunks</span>: {
      <span class="hljs-attr">chunks</span>: <span class="hljs-string">'all'</span>,
      <span class="hljs-attr">minSize</span>: <span class="hljs-number">10000</span>,
      <span class="hljs-attr">maxSize</span>: <span class="hljs-number">0</span>,
      <span class="hljs-attr">minChunks</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">maxAsyncRequests</span>: <span class="hljs-number">5</span>,
      <span class="hljs-attr">maxInitialRequests</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">automaticNameDelimiter</span>: <span class="hljs-string">'~'</span>,
      <span class="hljs-attr">name</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">cacheGroups</span>: {
        <span class="hljs-attr">vendors</span>: {
          <span class="hljs-attr">test</span>: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
          priority: <span class="hljs-number">-10</span>,
          <span class="hljs-attr">filename</span>: <span class="hljs-string">'vendors.js'</span>,
        },
        <span class="hljs-attr">default</span>: {
          <span class="hljs-attr">minChunks</span>: <span class="hljs-number">2</span>,
          <span class="hljs-attr">priority</span>: <span class="hljs-number">-20</span>,
          <span class="hljs-attr">reuseExistingChunk</span>: <span class="hljs-literal">true</span>,
          <span class="hljs-attr">filename</span>: <span class="hljs-string">'common.js'</span>,
        },
      },
    },
  },
};
</code></pre>
<h2 id="heading-module-concatenation">Module Concatenation</h2>
<p>Enable <code>ModuleConcatenationPlugin</code> to inline and reuse modules, reducing output file count and size.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> ModuleConcatenationPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack/lib/optimize/ModuleConcatenationPlugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> ModuleConcatenationPlugin(),
  ],
};
</code></pre>
<h2 id="heading-optimizing-loader-configuration">Optimizing Loader Configuration</h2>
<p>For CSS, use <code>css-loader</code>’s <code>importLoaders</code> to control preprocessor order. Add Autoprefixer with <code>postcss-loader</code>. Compress images with <code>image-webpack-loader</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mini-css-extract-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [
          MiniCssExtractPlugin.loader,
          <span class="hljs-string">'css-loader?importLoaders=1'</span>, <span class="hljs-comment">// 1 preprocessor (postcss-loader)</span>
          <span class="hljs-string">'postcss-loader'</span>,
        ],
      },
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|jpe?g|gif)$/i</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'file-loader'</span>,
            <span class="hljs-attr">options</span>: {},
          },
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'image-webpack-loader'</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">mozjpeg</span>: {
                <span class="hljs-attr">progressive</span>: <span class="hljs-literal">true</span>,
              },
              <span class="hljs-attr">gifsicle</span>: {
                <span class="hljs-attr">interlaced</span>: <span class="hljs-literal">false</span>,
              },
              <span class="hljs-attr">optipng</span>: {
                <span class="hljs-attr">optimizationLevel</span>: <span class="hljs-number">7</span>,
              },
              <span class="hljs-attr">pngquant</span>: {
                <span class="hljs-attr">quality</span>: [<span class="hljs-number">0.75</span>, <span class="hljs-number">0.90</span>],
                <span class="hljs-attr">speed</span>: <span class="hljs-number">4</span>,
              },
            },
          },
        ],
      },
    ],
  },
};
</code></pre>
<h2 id="heading-code-coverage-reporting">Code Coverage Reporting</h2>
<p>During testing, use <code>istanbul-instrumenter-loader</code> to calculate code coverage.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
        enforce: <span class="hljs-string">'post'</span>,
        <span class="hljs-attr">include</span>: <span class="hljs-regexp">/src/</span>,
        use: [{
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'istanbul-instrumenter-loader'</span>,
          <span class="hljs-attr">options</span>: { <span class="hljs-attr">esModules</span>: <span class="hljs-literal">true</span> },
        }],
        <span class="hljs-attr">exclude</span>: [<span class="hljs-regexp">/node_modules/</span>, <span class="hljs-regexp">/\.spec\.js$/</span>],
      },
    ],
  },
};
</code></pre>
<h2 id="heading-automated-deployment-and-monitoring">Automated Deployment and Monitoring</h2>
<p>Integrate CI/CD tools like Jenkins, Travis CI, or CircleCI to automate build, test, and deployment processes. Use monitoring tools like Sentry or New Relic to track application performance.</p>
]]></content:encoded></item><item><title><![CDATA[React Router v6 Latest Advances in Route Management]]></title><description><![CDATA[React Router v6 is a significant update for route management in React applications, introducing improvements and simplifications, including better handling of nested routes and enhanced use of hooks.
1. Routes Refactor
In v6, the <Route> component is...]]></description><link>https://tech.tianyaschool.com/react-router-v6-latest-advances-in-route-management</link><guid isPermaLink="true">https://tech.tianyaschool.com/react-router-v6-latest-advances-in-route-management</guid><category><![CDATA[react router]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Thu, 22 Jan 2026 14:24:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zwsHjakE_iI/upload/d7a81648590f779ee4c5d2145c2f3d41.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>React Router v6 is a significant update for route management in React applications, introducing improvements and simplifications, including better handling of nested routes and enhanced use of hooks.</p>
<h2 id="heading-1-routes-refactor">1. Routes Refactor</h2>
<p>In v6, the <code>&lt;Route&gt;</code> component is wrapped within a <code>&lt;Routes&gt;</code> component, replacing the <code>&lt;Switch&gt;</code> component. <code>&lt;Routes&gt;</code> automatically renders the first matching route.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { BrowserRouter <span class="hljs-keyword">as</span> Router, Routes, Route } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/about"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">About</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/users/*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Users</span> /&gt;</span>} /&gt; {/* Wildcard support */}
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-2-using-the-element-property">2. Using the <code>element</code> Property</h2>
<p>Routes now specify the component to render using the <code>element</code> property, replacing <code>component</code> or <code>render</code> functions.</p>
<pre><code class="lang-jsx">&lt;Route path=<span class="hljs-string">"/profile/:userId"</span> element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Profile</span> /&gt;</span></span>} /&gt;
</code></pre>
<h2 id="heading-3-hook-api">3. Hook API</h2>
<p>React Router v6 introduces hooks like <code>useParams</code>, <code>useLocation</code>, and <code>useNavigate</code>, enabling direct navigation handling within components.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useParams } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Profile</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { userId } = useParams();
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Profile of user {userId}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<h2 id="heading-4-navigate-function">4. Navigate Function</h2>
<p>The <code>useNavigate</code> hook returns a <code>navigate</code> function for programmatic navigation.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ProfileForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> navigate = useNavigate();
  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    event.preventDefault();
    <span class="hljs-comment">// Navigate to another page after form submission</span>
    navigate(<span class="hljs-string">'/success'</span>, { <span class="hljs-attr">replace</span>: <span class="hljs-literal">true</span> }); <span class="hljs-comment">// Replace current history entry</span>
  };

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>;
}
</code></pre>
<h2 id="heading-5-lazy-loading-and-code-splitting">5. Lazy Loading and Code Splitting</h2>
<p>React Router v6 supports dynamic imports for code splitting, improving load times.</p>
<pre><code class="lang-jsx">&lt;Route path=<span class="hljs-string">"/lazy"</span> element={<span class="hljs-keyword">import</span>(<span class="hljs-string">'./LazyComponent'</span>).then(<span class="hljs-function">(<span class="hljs-params">mod</span>) =&gt;</span> mod.LazyComponent)} /&gt;
</code></pre>
<h2 id="heading-6-404-page">6. 404 Page</h2>
<p>Handle unmatched routes with a wildcard route to display a 404 page.</p>
<pre><code class="lang-jsx">&lt;Route path=<span class="hljs-string">"*"</span> element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Error404</span> /&gt;</span></span>} /&gt;
</code></pre>
<h2 id="heading-7-nested-routes">7. Nested Routes</h2>
<p>Nested routes are simplified using <code>&lt;Routes&gt;</code> and <code>&lt;Route&gt;</code> combinations.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">MainLayout</span> /&gt;</span>}&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">index</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"about"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">About</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"users"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Users</span> /&gt;</span>}&gt;
            <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">":userId"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">User</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Error404</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-8-route-protection-and-authorization">8. Route Protection and Authorization</h2>
<p>Use <code>useEffect</code> or <code>useLayoutEffect</code> with <code>useNavigate</code> to protect routes, ensuring only authenticated users access them.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useNavigate, useLocation } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PrivateRoute</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">const</span> location = useLocation();
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!isAuthenticated()) {
      navigate(<span class="hljs-string">'/login'</span>, { <span class="hljs-attr">replace</span>: <span class="hljs-literal">true</span> });
    }
  }, [navigate]);

  <span class="hljs-keyword">return</span> isAuthenticated() ? children : <span class="hljs-literal">null</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">PublicRoute</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">PublicRoute</span>&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/dashboard"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">PrivateRoute</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Dashboard</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">PrivateRoute</span>&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Login</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here, <code>isAuthenticated()</code> is a hypothetical function checking user authentication. Unauthenticated users are redirected to the login page.</p>
<h2 id="heading-9-redirects-and-navigation">9. Redirects and Navigation</h2>
<p>The <code>&lt;Navigate&gt;</code> component facilitates redirects by triggering navigation to a specified URL.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Navigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PrivateRoute</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">if</span> (!isAuthenticated()) {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">replace</span> /&gt;</span></span>;
  }

  <span class="hljs-keyword">return</span> children;
}
</code></pre>
<h2 id="heading-10-route-parameters-and-query-strings">10. Route Parameters and Query Strings</h2>
<p>Use <code>useParams</code> for route parameters and <code>useLocation</code> for query strings.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useParams, useLocation } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Profile</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { userId } = useParams();
  <span class="hljs-keyword">const</span> query = <span class="hljs-keyword">new</span> URLSearchParams(useLocation().search);
  <span class="hljs-keyword">const</span> searchParam = query.get(<span class="hljs-string">'paramName'</span>);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Profile of user {userId} with search param: {searchParam}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<h2 id="heading-11-custom-route-matching">11. Custom Route Matching</h2>
<p>React Router v6 supports custom route matching via the <code>path-to-regexp</code> library, though standard path patterns are usually sufficient.</p>
<h2 id="heading-12-higher-order-components-hocs">12. Higher-Order Components (HoCs)</h2>
<p>While v6 discourages HoCs, you can still wrap components for specific logic, such as route protection.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PrivateRoute</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">if</span> (!isAuthenticated()) {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">replace</span> /&gt;</span></span>;
  }

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;&gt;</span>{children}<span class="hljs-tag">&lt;/&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">PublicRoute</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">PublicRoute</span>&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/dashboard"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">PrivateRoute</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Dashboard</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">PrivateRoute</span>&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Login</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-13-route-events">13. Route Events</h2>
<p>React Router v6 provides lifecycle hooks like <code>useLocation</code> and <code>useNavigate</code> to monitor and respond to route changes.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useLocation } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Navbar</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> location = useLocation();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Navigated to <span class="hljs-subst">${location.pathname}</span>`</span>);
  }, [location]);

  <span class="hljs-keyword">return</span> <span class="hljs-comment">/* ... */</span>;
}
</code></pre>
<h2 id="heading-14-modular-route-configuration">14. Modular Route Configuration</h2>
<p>Keep code clean by splitting route configurations into modules and merging them in the main configuration.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// routes/users.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  { <span class="hljs-attr">path</span>: <span class="hljs-string">'/users'</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">UsersList</span> /&gt;</span></span> },
  { <span class="hljs-attr">path</span>: <span class="hljs-string">'/users/:id'</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">UserProfile</span> /&gt;</span></span> },
];

<span class="hljs-comment">// routes/admin.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  { <span class="hljs-attr">path</span>: <span class="hljs-string">'/admin/dashboard'</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AdminDashboard</span> /&gt;</span></span> },
  { <span class="hljs-attr">path</span>: <span class="hljs-string">'/admin/users'</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AdminUsers</span> /&gt;</span></span> },
];

<span class="hljs-comment">// App.js</span>
<span class="hljs-keyword">import</span> { BrowserRouter <span class="hljs-keyword">as</span> Router, Routes, Route } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;
<span class="hljs-keyword">import</span> usersRoutes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes/users'</span>;
<span class="hljs-keyword">import</span> adminRoutes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes/admin'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        {usersRoutes.map((route, index) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span> {<span class="hljs-attr">...route</span>} /&gt;</span>
        ))}
        {adminRoutes.map((route, index) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span> {<span class="hljs-attr">...route</span>} /&gt;</span>
        ))}
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">ErrorPage</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-15-route-guards">15. Route Guards</h2>
<p>Create custom guard functions to control route access, often for authorization or data preloading.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requireAuth</span>(<span class="hljs-params">nextState, replace</span>) </span>{
  <span class="hljs-keyword">if</span> (!isAuthenticated()) {
    replace({
      <span class="hljs-attr">pathname</span>: <span class="hljs-string">'/login'</span>,
      <span class="hljs-attr">state</span>: { <span class="hljs-attr">nextPathname</span>: nextState.location.pathname },
    });
  }
}

<span class="hljs-comment">// In routes</span>
&lt;Route path=<span class="hljs-string">"/protected"</span> onEnter={requireAuth} element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ProtectedComponent</span> /&gt;</span></span>} /&gt;
</code></pre>
<p>In v6, use <code>useEffect</code> or <code>useLayoutEffect</code> for similar functionality.</p>
<h2 id="heading-16-nested-routing">16. Nested Routing</h2>
<p>Nested routes are handled without explicitly wrapping <code>&lt;Switch&gt;</code>, using nested <code>&lt;Routes&gt;</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">MainLayout</span> /&gt;</span>}&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">index</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"about"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">About</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"users"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Users</span> /&gt;</span>}&gt;
            <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">":userId"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">User</span> /&gt;</span>} /&gt;
          <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"*"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Error404</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here, <code>/users/:userId</code> is defined within <code>/users</code>, rendering both <code>Users</code> and <code>User</code> components for <code>/users/someId</code>.</p>
<h2 id="heading-17-custom-error-handling">17. Custom Error Handling</h2>
<p>React Router v6 doesn’t provide global error handling, but you can use <code>window.onerror</code> or custom middleware.</p>
<h2 id="heading-18-code-splitting-and-lazy-loading">18. Code Splitting and Lazy Loading</h2>
<p>React Router v6 integrates with Webpack or other bundlers for code splitting and lazy loading using dynamic <code>import()</code>:</p>
<pre><code class="lang-jsx">&lt;Route
  path=<span class="hljs-string">"/lazy"</span>
  element={
    <span class="hljs-keyword">import</span>(<span class="hljs-string">'./LazyComponent'</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">mod</span>) =&gt;</span> mod.LazyComponent)
      .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ErrorBoundary</span> <span class="hljs-attr">error</span>=<span class="hljs-string">{error}</span> /&gt;</span></span>)
  }
/&gt;
</code></pre>
<h2 id="heading-19-custom-route-components">19. Custom Route Components</h2>
<p>While the <code>&lt;Route&gt;</code> component is simplified, you can create custom components to extend functionality, such as adding loading indicators.</p>
<h2 id="heading-20-server-side-rendering-ssr">20. Server-Side Rendering (SSR)</h2>
<p>React Router v6 supports SSR with additional configuration and libraries like <code>react-router-dom/server</code> and <code>react-router-dom/browser</code>.</p>
]]></content:encoded></item><item><title><![CDATA[SvelteKit A New Framework for Building High-Performance SSR Applications]]></title><description><![CDATA[SvelteKit is a next-generation framework based on Svelte, designed for building server-side rendered (SSR) and static site generated (SSG) applications. Svelte is a lightweight frontend framework known for its exceptional performance and concise code...]]></description><link>https://tech.tianyaschool.com/sveltekit-a-new-framework-for-building-high-performance-ssr-applications</link><guid isPermaLink="true">https://tech.tianyaschool.com/sveltekit-a-new-framework-for-building-high-performance-ssr-applications</guid><category><![CDATA[Sveltekit]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Svelte]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Wed, 17 Dec 2025 15:02:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/MSN8TFhJ0is/upload/fbd93e5b86730500f1d8fef05416ccbf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>SvelteKit is a next-generation framework based on Svelte, designed for building server-side rendered (SSR) and static site generated (SSG) applications. Svelte is a lightweight frontend framework known for its exceptional performance and concise code. SvelteKit extends Svelte’s capabilities, providing a complete development workflow, including routing, data fetching, API calls, and server-side rendering.</p>
<h2 id="heading-svelte-components">Svelte Components</h2>
<p>SvelteKit applications are built on Svelte components, which are reusable UI blocks. A typical Svelte component includes three main sections:</p>
<ul>
<li><p><code>&lt;script&gt;</code> tag: Defines component state, logic, and module imports.</p>
</li>
<li><p><code>&lt;style&gt;</code> tag: Specifies private styles scoped to the component, preventing leakage to other components.</p>
</li>
<li><p>HTML or Svelte syntax: Defines the component’s template, determining what is rendered.</p>
</li>
</ul>
<p>Here’s an example of a simple Svelte component, <code>Hello.svelte</code>:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-comment">// Define component state</span>
  <span class="hljs-keyword">let</span> name = <span class="hljs-string">'World'</span>;

  <span class="hljs-comment">// Export variables as component props</span>
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> greeting = <span class="hljs-string">'Hello'</span>;
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

</span><span class="hljs-comment">&lt;!-- HTML/Svelte template --&gt;</span><span class="xml">
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span><span class="javascript">{greeting}</span><span class="xml">, </span><span class="javascript">{name}</span><span class="xml">!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span></span><span class="css">
  <span class="hljs-comment">/* Private component styles */</span>
  <span class="hljs-selector-tag">h1</span> {
    <span class="hljs-attribute">color</span>: blue;
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span>
</code></pre>
<h3 id="heading-reactive-variables">Reactive Variables</h3>
<p>In the <code>&lt;script&gt;</code> tag, variables are reactive by default. Svelte automatically tracks changes and updates the view when they occur. In the example above, <code>name</code> and <code>greeting</code> are reactive.</p>
<h3 id="heading-exported-props">Exported Props</h3>
<p>Using the <code>export</code> keyword, variables can be exposed as component props, allowing parent components to pass values. In the example, <code>greeting</code> is an exportable prop.</p>
<h3 id="heading-computed-properties-and-methods">Computed Properties and Methods</h3>
<p>Svelte supports computed properties and methods in the <code>&lt;script&gt;</code> tag, calculated based on reactive variables:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
</span><span class="hljs-keyword">  $: </span><span class="javascript">doubledCount = count * <span class="hljs-number">2</span>;

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    count += <span class="hljs-number">1</span>;
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=</span></span><span class="javascript">{increment}</span><span class="xml"><span class="hljs-tag">&gt;</span></span><span class="javascript">{count}</span><span class="xml"> or </span><span class="javascript">{doubledCount}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
<h3 id="heading-conditional-rendering-and-loops">Conditional Rendering and Loops</h3>
<p>Svelte supports conditional rendering (<code>if</code> and <code>else</code>) and loops (<code>each</code>) for dynamic content:</p>
<pre><code class="lang-svelte"><span class="javascript">{</span><span class="hljs-keyword">#if</span><span class="javascript"> showing}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Visible content<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</span><span class="javascript">{</span><span class="hljs-keyword">:else</span><span class="javascript">}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hidden content<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</span><span class="javascript">{</span><span class="hljs-keyword">/if</span><span class="javascript">}</span><span class="xml">

</span><span class="javascript">{</span><span class="hljs-keyword">#each</span><span class="javascript"> items <span class="hljs-keyword">as</span> item}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><span class="javascript">{item.name}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</span><span class="javascript">{</span><span class="hljs-keyword">/each</span><span class="javascript">}</span>
</code></pre>
<h3 id="heading-event-handling">Event Handling</h3>
<p>Svelte uses the <code>on:</code> prefix to listen for and handle DOM events:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=</span></span><span class="javascript">{handleClick}</span><span class="xml"><span class="hljs-tag">&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
<h3 id="heading-custom-directives">Custom Directives</h3>
<p>Svelte provides custom directives like <code>bind:</code> and <code>use:</code> to extend component behavior. For example, <code>bind:</code> enables two-way binding:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">bind:value</span>=</span></span><span class="javascript">{name}</span><span class="xml"><span class="hljs-tag"> /&gt;</span></span>
</code></pre>
<h3 id="heading-lifecycle-hooks">Lifecycle Hooks</h3>
<p>Svelte offers lifecycle functions like <code>onMount</code>, <code>beforeUpdate</code>, and <code>onDestroy</code> for executing code at specific component stages:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">import</span> { onMount, onDestroy } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte'</span>;

  <span class="hljs-keyword">let</span> mounted = <span class="hljs-literal">false</span>;

  onMount(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component has been mounted'</span>);
    mounted = <span class="hljs-literal">true</span>;
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cleanup</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component is being destroyed'</span>);
  }

  onDestroy(cleanup);
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h2 id="heading-routing">Routing</h2>
<h3 id="heading-1-routing-structure">1. Routing Structure</h3>
<p>SvelteKit’s routing is tightly coupled with the file system in the <code>src/routes</code> directory. Each directory or file corresponds to a route:</p>
<ul>
<li><p><code>src/routes/index.svelte</code>: The app’s homepage.</p>
</li>
<li><p><code>src/routes/blog/[slug].svelte</code>: A blog post page, where <code>[slug]</code> is a dynamic parameter.</p>
</li>
</ul>
<h3 id="heading-2-static-routes">2. Static Routes</h3>
<p>Static routes map fixed URLs to Svelte components. For example, <code>src/routes/about.svelte</code> matches the <code>/about</code> path.</p>
<h3 id="heading-3-dynamic-routes">3. Dynamic Routes</h3>
<p>Dynamic routes capture URL segments as parameters, denoted by square brackets (e.g., <code>[id]</code>). In the blog example, <code>[slug]</code> captures strings like <code>/blog/my-first-post</code>, passing <code>my-first-post</code> as the <code>slug</code> parameter.</p>
<h4 id="heading-load-function">Load Function</h4>
<p>Each route component can define a <code>load</code> function to fetch data on the server or client, returning a Promise whose result becomes component props:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">context</span>=<span class="hljs-string">"module"</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load</span>(<span class="hljs-params">{ params }</span>) </span>{
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/posts/<span class="hljs-subst">${params.slug}</span>`</span>);
    <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">props</span>: { post } };
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> post;
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span><span class="javascript">{post.title}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span></span><span class="javascript">{post.content}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<h3 id="heading-4-api-routes">4. API Routes</h3>
<p>SvelteKit supports API endpoints by creating <code>.js</code> or <code>.ts</code> files in <code>src/routes</code> instead of <code>.svelte</code> files. For example, <code>src/routes/api/posts.js</code> handles requests to <code>/api/posts</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params">{ params }</span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://api.example.com/posts/<span class="hljs-subst">${params.id}</span>`</span>);
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">body</span>: <span class="hljs-keyword">await</span> response.json(),
  };
}
</code></pre>
<h3 id="heading-5-middleware">5. Middleware</h3>
<p>SvelteKit allows middleware files, like <code>_middleware.js</code> in <code>src/routes</code>, to handle all route requests for tasks like authentication or logging:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params">{ request, resolve }</span>) </span>{
  <span class="hljs-keyword">const</span> token = request.headers.get(<span class="hljs-string">'Authorization'</span>);

  <span class="hljs-keyword">if</span> (validateToken(token)) {
    <span class="hljs-keyword">return</span> resolve(request);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Unauthorized'</span>);
  }
}
</code></pre>
<h3 id="heading-6-route-navigation">6. Route Navigation</h3>
<p>Use the <code>goto</code> function for client-side navigation or apply the <code>use:link</code> action to <code>&lt;a&gt;</code> tags:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">import</span> { goto } <span class="hljs-keyword">from</span> <span class="hljs-string">'$app/navigation'</span>;
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=</span></span><span class="javascript">{<span class="hljs-function">() =&gt;</span> goto(<span class="hljs-string">'/about'</span>)}</span><span class="xml"><span class="hljs-tag">&gt;</span>
  Go to About Page
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/about"</span> <span class="hljs-attr">use:link</span>&gt;</span>Go to About Page<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>
</code></pre>
<h3 id="heading-7-route-parameters-and-query-strings">7. Route Parameters and Query Strings</h3>
<p>Pass route parameters and query strings with <code>goto</code>:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">import</span> { goto } <span class="hljs-keyword">from</span> <span class="hljs-string">'$app/navigation'</span>;
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=</span></span><span class="javascript">{<span class="hljs-function">() =&gt;</span> goto(<span class="hljs-string">'/blog/some-post'</span>, { <span class="hljs-attr">id</span>: <span class="hljs-number">123</span> })}</span><span class="xml"><span class="hljs-tag">&gt;</span>
  View Post
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
<h2 id="heading-data-fetching">Data Fetching</h2>
<p>SvelteKit provides a flexible data-fetching mechanism via the <code>load</code> function, used during SSR, client initialization, and navigation.</p>
<h3 id="heading-1-load-function">1. Load Function</h3>
<p>The <code>load</code> function runs when a page loads, fetching data and returning props for the component:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">context</span>=<span class="hljs-string">"module"</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load</span>(<span class="hljs-params">{ page, session }</span>) </span>{
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">props</span>: { data } };
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> data;
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  </span><span class="javascript">{</span><span class="hljs-keyword">#each</span><span class="javascript"> data <span class="hljs-keyword">as</span> item}</span><span class="xml">
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span></span><span class="javascript">{item.name}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  </span><span class="javascript">{</span><span class="hljs-keyword">/each</span><span class="javascript">}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
</code></pre>
<h3 id="heading-2-load-function-parameters">2. Load Function Parameters</h3>
<ul>
<li><p><code>page</code>: Contains route information, like <code>page.params</code> (dynamic route parameters) and <code>page.query</code> (query string parameters).</p>
</li>
<li><p><code>session</code>: Stores user session data, useful for authentication.</p>
</li>
</ul>
<h3 id="heading-3-separating-client-and-server-logic">3. Separating Client and Server Logic</h3>
<p>The <code>load</code> function can differentiate between client and server logic:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">context</span>=<span class="hljs-string">"module"</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load</span>(<span class="hljs-params">{ page, session }</span>) </span>{
    <span class="hljs-keyword">let</span> data;

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">import</span>.meta.env.SSR) {
      <span class="hljs-comment">// Server-side logic</span>
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// Client-side logic</span>
    }

    <span class="hljs-keyword">return</span> { <span class="hljs-attr">props</span>: { data } };
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h3 id="heading-4-caching-and-redirects">4. Caching and Redirects</h3>
<p>The <code>load</code> function can return <code>status</code>, <code>headers</code>, and <code>redirect</code> properties to control HTTP responses:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">context</span>=<span class="hljs-string">"module"</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load</span>(<span class="hljs-params">{ page }</span>) </span>{
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
    <span class="hljs-keyword">if</span> (response.status === <span class="hljs-number">401</span>) {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">status</span>: <span class="hljs-number">401</span>,
        <span class="hljs-attr">redirect</span>: <span class="hljs-string">'/login'</span>,
      };
    }

    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">props</span>: { data } };
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h3 id="heading-5-client-side-data-updates">5. Client-Side Data Updates</h3>
<p>The <code>load</code> function can rerun during navigation or component updates to refresh data, using the <code>page.changed</code> property:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">context</span>=<span class="hljs-string">"module"</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load</span>(<span class="hljs-params">{ page }</span>) </span>{
    <span class="hljs-keyword">if</span> (page.changed.query) {
      <span class="hljs-comment">// Query string changed, refetch data</span>
    }
    <span class="hljs-comment">// ...</span>
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h2 id="heading-server-side-rendering-ssr">Server-Side Rendering (SSR)</h2>
<p>SvelteKit supports SSR by default, rendering full HTML on initial load for better SEO and faster first-paint times. The <code>load</code> function executes server-side, and the fetched data is rendered into HTML.</p>
<h2 id="heading-static-site-generation-ssg">Static Site Generation (SSG)</h2>
<p>SvelteKit supports SSG for prerendering static HTML pages. Running <code>svelte-kit build</code> in production generates a static site deployable to any static hosting service.</p>
<h2 id="heading-api-routes">API Routes</h2>
<p>Beyond page routes, SvelteKit supports API routes via <code>.js</code> or <code>.ts</code> files in <code>src/routes</code>. For example, <code>src/routes/api/data.js</code> handles <code>/api/data</code> requests:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params">request</span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">body</span>: <span class="hljs-keyword">await</span> response.json(),
  };
}
</code></pre>
<h2 id="heading-authentication-and-middleware">Authentication and Middleware</h2>
<p>Reusable middleware can be written in the <code>src/lib</code> directory, running at different stages of the request lifecycle. For example, an authentication middleware:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/lib/auth.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">authenticate</span>(<span class="hljs-params">req, res, next</span>) </span>{
  <span class="hljs-keyword">const</span> token = req.headers.authorization || <span class="hljs-string">''</span>;
  <span class="hljs-keyword">if</span> (validateToken(token)) {
    next();
  } <span class="hljs-keyword">else</span> {
    res.status(<span class="hljs-number">401</span>).end();
  }
}
</code></pre>
<p>Use it in <code>src/routes/_middleware.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { authenticate } <span class="hljs-keyword">from</span> <span class="hljs-string">'../lib/auth.js'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params">{ request, resolve }</span>) </span>{
  authenticate(request);
  <span class="hljs-keyword">return</span> resolve(request);
}
</code></pre>
<h2 id="heading-deployment-and-configuration">Deployment and Configuration</h2>
<p>SvelteKit offers flexible deployment options for platforms like Vercel, Netlify, or AWS Amplify. Configure the target platform using adapters:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// svelte.config.js</span>
<span class="hljs-keyword">import</span> adapter <span class="hljs-keyword">from</span> <span class="hljs-string">'@sveltejs/adapter-node'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">kit</span>: {
    <span class="hljs-attr">adapter</span>: adapter(),
  },
};
</code></pre>
<h2 id="heading-page-transitions">Page Transitions</h2>
<p>SvelteKit supports smooth page transitions using the <code>&lt;transition&gt;</code> and <code>&lt;route&gt;</code> components within <code>&lt;svelte:head&gt;</code>:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">svelte:head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
    <span class="hljs-keyword">import</span> { crossfade } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte/transition'</span>;

    <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> data;
    <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> component;

    <span class="hljs-keyword">let</span> transition;
</span><span class="hljs-keyword">    $: </span><span class="javascript">transition = component ? crossfade : <span class="hljs-literal">null</span>;
</span><span class="xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

  </span><span class="javascript">{</span><span class="hljs-keyword">#if</span><span class="javascript"> transition}</span><span class="xml">
    <span class="hljs-tag">&lt;<span class="hljs-name">transition</span>
      <span class="hljs-attr">bind:this</span>=</span></span><span class="javascript">{transition}</span><span class="xml"><span class="hljs-tag">
      <span class="hljs-attr">duration</span>=</span></span><span class="javascript">{<span class="hljs-number">300</span>}</span><span class="xml"><span class="hljs-tag">
      <span class="hljs-attr">outDuration</span>=</span></span><span class="javascript">{<span class="hljs-number">200</span>}</span><span class="xml"><span class="hljs-tag">
      <span class="hljs-attr">in</span>=</span></span><span class="javascript">{component !== data.component}</span><span class="xml"><span class="hljs-tag">
      <span class="hljs-attr">out</span>=</span></span><span class="javascript">{component === data.component}</span><span class="xml"><span class="hljs-tag">
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">transition</span>&gt;</span>
  </span><span class="javascript">{</span><span class="hljs-keyword">:else</span><span class="javascript">}</span><span class="xml">
    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
  </span><span class="javascript">{</span><span class="hljs-keyword">/if</span><span class="javascript">}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">svelte:head</span>&gt;</span></span>
</code></pre>
<p>This code implements a crossfade transition, smoothly fading between pages when the component changes.</p>
<h2 id="heading-client-side-routing-and-navigation">Client-Side Routing and Navigation</h2>
<p>Use the <code>goto</code> function or <code>$navigate</code> store for client-side navigation, or apply the <code>use:link</code> action to <code>&lt;a&gt;</code> tags:</p>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-keyword">import</span> { navigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'$app/navigation'</span>;

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
    navigate(<span class="hljs-string">'/another-page'</span>);
  }
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=</span></span><span class="javascript">{handleClick}</span><span class="xml"><span class="hljs-tag">&gt;</span>Go to Another Page<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/another-page"</span> <span class="hljs-attr">use:link</span>&gt;</span>Another Page<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>
</code></pre>
<h2 id="heading-adapters">Adapters</h2>
<p>Adapters allow SvelteKit apps to be packaged for specific platforms. For example, <code>@sveltejs/adapter-node</code> targets Node.js servers, while <code>@sveltejs/adapter-static</code> generates static sites.</p>
<h2 id="heading-service-workers-and-offline-support">Service Workers and Offline Support</h2>
<p>SvelteKit supports Progressive Web App (PWA) features, including offline support, via the <code>@sveltejs/adapter-workbox</code> adapter, enabling service workers for basic functionality without a network.</p>
<h2 id="heading-static-asset-handling">Static Asset Handling</h2>
<p>SvelteKit automatically handles static assets like images, CSS, and JavaScript. Place files in the <code>static</code> directory, and SvelteKit copies and references them during the build. For example, <code>static/images/logo.png</code> is accessible at <code>/images/logo.png</code>.</p>
<h2 id="heading-environment-variables-and-configuration">Environment Variables and Configuration</h2>
<p>SvelteKit supports environment variables for different environments (e.g., development, production). Define them in <code>.env</code> files or <code>svelte.config.js</code> and access them via <code>import.meta.env</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// svelte.config.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">kit</span>: {
    <span class="hljs-attr">vite</span>: {
      <span class="hljs-attr">define</span>: {
        <span class="hljs-string">'process.env.API_KEY'</span>: <span class="hljs-built_in">JSON</span>.stringify(process.env.API_KEY),
      },
    },
  },
};
</code></pre>
<pre><code class="lang-svelte"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span><span class="javascript">
  <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">import</span>.meta.env.VITE_API_KEY);
</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<h2 id="heading-type-safety-and-typescript-support">Type Safety and TypeScript Support</h2>
<p>SvelteKit fully supports TypeScript for type safety. Rename <code>.svelte</code> files to <code>.svelte.ts</code> and configure TypeScript to enable type hints and error checking.</p>
<p>SvelteKit combines tools for building high-performance SSR applications with an excellent developer experience, flexibility, and ease of use, making it a powerful choice for modern web development.</p>
]]></content:encoded></item><item><title><![CDATA[Angular Ivy Performance Enhancements and Optimizations of the New Rendering Engine]]></title><description><![CDATA[Angular Ivy, introduced as the default rendering engine in Angular 9 and later, replaces the previous View Engine. Ivy aims to improve Angular’s performance, reduce bundle sizes, and enhance developer productivity.
1. Improved AOT Compilation
Ivy emp...]]></description><link>https://tech.tianyaschool.com/angular-ivy-performance-enhancements-and-optimizations-of-the-new-rendering-engine</link><guid isPermaLink="true">https://tech.tianyaschool.com/angular-ivy-performance-enhancements-and-optimizations-of-the-new-rendering-engine</guid><category><![CDATA[Angular]]></category><category><![CDATA[Angular 2]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Fri, 14 Nov 2025 11:07:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zwsHjakE_iI/upload/7c6e88a365a54ddd1270898861362687.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Angular Ivy, introduced as the default rendering engine in Angular 9 and later, replaces the previous View Engine. Ivy aims to improve Angular’s performance, reduce bundle sizes, and enhance developer productivity.</p>
<h2 id="heading-1-improved-aot-compilation">1. Improved AOT Compilation</h2>
<p>Ivy employs earlier Ahead-of-Time (AOT) compilation, converting templates into pure JavaScript during the build process, reducing runtime compilation overhead. Unlike View Engine, which generated large metadata files, Ivy inlines metadata directly into component classes, decreasing load times.</p>
<h2 id="heading-2-smaller-output-size">2. Smaller Output Size</h2>
<p>Ivy produces smaller code due to its compact metadata format and support for finer-grained lazy-loaded module splitting. This ensures users download only the code they need, not the entire application.</p>
<h2 id="heading-3-faster-startup-time">3. Faster Startup Time</h2>
<p>Ivy’s metadata structure and optimized compilation process result in faster application startup. The new metadata format reduces parsing and initialization time.</p>
<h2 id="heading-4-enhanced-type-checking-and-error-reporting">4. Enhanced Type Checking and Error Reporting</h2>
<p>Ivy provides improved type checking during the build phase, catching more errors at compile time rather than runtime. This boosts development efficiency and reduces potential runtime issues.</p>
<h2 id="heading-5-simplified-library-development">5. Simplified Library Development</h2>
<p>Ivy allows library authors to use Ivy compilation directly without additional configuration, simplifying library creation and maintenance while benefiting library users.</p>
<h2 id="heading-6-optimized-dynamic-components">6. Optimized Dynamic Components</h2>
<p>Ivy enhances support for dynamic components, reducing the overhead of creating and destroying them, a significant performance boost for applications with frequent component lifecycle changes.</p>
<h2 id="heading-7-more-efficient-dependency-injection-di">7. More Efficient Dependency Injection (DI)</h2>
<p>Ivy’s dependency injection system is more efficient, minimizing the overhead of dependency lookup, especially in large applications.</p>
<h2 id="heading-8-improved-tree-shaking">8. Improved Tree Shaking</h2>
<p>Tree shaking, a feature of modern JavaScript bundlers, removes unused code. Ivy’s design makes tree shaking more effective, further reducing final bundle sizes.</p>
<p>To enable Ivy, no special configuration is typically needed in Angular 9 and above, as it’s the default. However, you can manually enable or disable it in the <code>angular.json</code> or <a target="_blank" href="http://tsconfig.app"><code>tsconfig.app</code></a><code>.json</code> file:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"enableIvy"</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<h2 id="heading-9-local-scope-for-modules-and-directives">9. Local Scope for Modules and Directives</h2>
<p>Ivy introduces local scoping for modules and directives, allowing components to declare their own directives or pipes without polluting the global namespace. This reduces potential conflicts and improves code organization and maintainability.</p>
<h2 id="heading-10-enhanced-change-detection">10. Enhanced Change Detection</h2>
<p>Ivy optimizes change detection, precisely tracking which components need updates. It introduces the “Incremental DOM Builder,” updating only parts of the DOM where data has changed, reducing unnecessary operations and boosting performance.</p>
<h2 id="heading-11-ongoing-performance-optimizations">11. Ongoing Performance Optimizations</h2>
<p>The Angular team continuously refines Ivy, reducing runtime code, improving data binding, and enhancing startup and runtime performance.</p>
<p>Here’s a simple Angular component example showcasing Ivy’s features:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app.component.ts</span>
<span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-root'</span>,
  template: <span class="hljs-string">`
    &lt;h1&gt;{{ title }}&lt;/h1&gt;
    &lt;button (click)="changeTitle()"&gt;Change Title&lt;/button&gt;
  `</span>,
  styles: []
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent {
  title = <span class="hljs-string">'Angular Ivy App'</span>;

  changeTitle() {
    <span class="hljs-built_in">this</span>.title = <span class="hljs-string">'New Title'</span>;
  }
}
</code></pre>
<p>In this code, Ivy’s AOT compilation converts the template into efficient JavaScript, minimizing runtime parsing. The change detection mechanism monitors the <code>title</code> property, updating the view only when <code>changeTitle()</code> modifies it.</p>
<h2 id="heading-12-tree-shakable-services-and-dependencies">12. Tree-Shakable Services and Dependencies</h2>
<p>Ivy enables tree shaking for services, excluding unused service code from the final bundle. This is achieved using the <code>@Injectable({ providedIn: 'root' })</code> decorator, which provides the service at the root level while allowing tree shakers to identify unused services.</p>
<h2 id="heading-13-lazy-loading-and-preloading-strategies">13. Lazy Loading and Preloading Strategies</h2>
<p>Ivy supports fine-grained lazy loading and preloading, crucial for large applications. Lazy loading loads modules on-demand when users navigate to specific routes, reducing initial load time. Preloading loads modules in the background to improve user experience.</p>
<p>Lazy loading in Angular is straightforward with the Router:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app-routing.module.ts</span>
<span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { RouterModule, Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { HomeComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./home/home.component'</span>;

<span class="hljs-keyword">const</span> routes: Routes = [
  { path: <span class="hljs-string">''</span>, component: HomeComponent },
  { path: <span class="hljs-string">'about'</span>, loadChildren: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./about/about.module'</span>).then(<span class="hljs-function"><span class="hljs-params">m</span> =&gt;</span> m.AboutModule) }, <span class="hljs-comment">// Lazy load About module</span>
];

<span class="hljs-meta">@NgModule</span>({
  imports: [RouterModule.forRoot(routes)],
  <span class="hljs-built_in">exports</span>: [RouterModule]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<p>Preloading can be configured using the <code>preloadingStrategy</code> option, with <code>PreloadAllModules</code> to preload all lazy-loaded modules:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// main.ts or app.module.ts</span>
<span class="hljs-keyword">import</span> { BrowserModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;
<span class="hljs-keyword">import</span> { NgModule, PreloadAllModules } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { RouterModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.component'</span>;
<span class="hljs-keyword">import</span> { AppRoutingModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app-routing.module'</span>;

<span class="hljs-meta">@NgModule</span>({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(AppRoutingModule.routes, { preloadingStrategy: PreloadAllModules }) <span class="hljs-comment">// Preload all modules</span>
  ],
  providers: [],
  bootstrap: [AppComponent]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
</code></pre>
<h2 id="heading-14-angular-elements">14. Angular Elements</h2>
<p>Ivy supports Angular Elements, allowing Angular components to be packaged as Web Components for use in any platform supporting Web Component standards, including non-Angular apps, enhancing reusability and cross-framework compatibility.</p>
<h2 id="heading-15-performance-monitoring-and-diagnostics">15. Performance Monitoring and Diagnostics</h2>
<p>Angular offers tools like Angular DevTools to analyze change detection, memory allocation, and rendering performance. Ivy’s improvements provide more accurate and detailed performance data for diagnostics and optimization.</p>
<h2 id="heading-16-internationalization-i18n-and-localization">16. Internationalization (i18n) and Localization</h2>
<p>Ivy enhances i18n support with flexible tagging and extraction mechanisms, streamlining multilingual app development and maintenance. Developers can use the <code>ng xi18n</code> command to extract translation tags and leverage tools or services for translations.</p>
]]></content:encoded></item><item><title><![CDATA[Vue.js Component Design Patterns-Building a Reusable Component Library]]></title><description><![CDATA[Creating a reusable component library in Vue.js is key to improving code reusability and maintainability. Below are design patterns and examples demonstrating how to build reusable Vue components.
1. Single File Component (SFC)
Vue.js components are ...]]></description><link>https://tech.tianyaschool.com/vuejs-component-design-patterns-building-a-reusable-component-library</link><guid isPermaLink="true">https://tech.tianyaschool.com/vuejs-component-design-patterns-building-a-reusable-component-library</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 18 Aug 2025 14:04:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/OGOWDVLbMSc/upload/3c685e8b8fed7fdfda6ca5897d1740d0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Creating a reusable component library in Vue.js is key to improving code reusability and maintainability. Below are design patterns and examples demonstrating how to build reusable Vue components.</p>
<h2 id="heading-1-single-file-component-sfc">1. Single File Component (SFC)</h2>
<p>Vue.js components are typically Single File Components, combining HTML, CSS, and JavaScript. Here’s an example of a reusable component:</p>
<pre><code class="lang-bash">&lt;template&gt;
  &lt;div class=<span class="hljs-string">"my-component"</span>&gt;
    &lt;h3&gt;{{ title }}&lt;/h3&gt;
    &lt;p&gt;{{ message }}&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
<span class="hljs-built_in">export</span> default {
  props: {
    title: String,
    message: String,
  },
};
&lt;/script&gt;

&lt;style scoped&gt;
.my-component {
  /* Custom styles */
}
&lt;/style&gt;
</code></pre>
<p>In this example, <code>title</code> and <code>message</code> are passed as <code>props</code>, allowing external customization of the component’s title and message.</p>
<h2 id="heading-2-component-props-and-default-values">2. Component Props and Default Values</h2>
<p>Props enable components to accept external data, with default values set using the <code>default</code> property:</p>
<pre><code class="lang-javascript">props: {
  <span class="hljs-attr">myProp</span>: {
    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">default</span>: <span class="hljs-string">'Default value'</span>,
  },
},
</code></pre>
<h2 id="heading-3-custom-events">3. Custom Events</h2>
<p>Use <code>$emit</code> to dispatch custom events, facilitating communication between parent and child components:</p>
<pre><code class="lang-javascript">methods: {
  handleClick() {
    <span class="hljs-built_in">this</span>.$emit(<span class="hljs-string">'my-event'</span>, <span class="hljs-string">'This is event data'</span>);
  },
},
</code></pre>
<h2 id="heading-4-slots">4. Slots</h2>
<p>Slots allow parent components to inject content into child components:</p>
<pre><code class="lang-bash">&lt;template&gt;
  &lt;div class=<span class="hljs-string">"container"</span>&gt;
    &lt;header&gt;
      &lt;slot name=<span class="hljs-string">"header"</span>&gt;&lt;/slot&gt;
    &lt;/header&gt;
    &lt;main&gt;
      &lt;slot&gt;&lt;/slot&gt;
    &lt;/main&gt;
    &lt;footer&gt;
      &lt;slot name=<span class="hljs-string">"footer"</span>&gt;&lt;/slot&gt;
    &lt;/footer&gt;
  &lt;/div&gt;
&lt;/template&gt;
</code></pre>
<p>Parent component usage:</p>
<pre><code class="lang-bash">&lt;MyComponent&gt;
  &lt;template v-slot:header&gt;
    &lt;h1&gt;This is the header&lt;/h1&gt;
  &lt;/template&gt;
  &lt;p&gt;This is the main content&lt;/p&gt;
  &lt;template v-slot:footer&gt;
    &lt;p&gt;This is the footer&lt;/p&gt;
  &lt;/template&gt;
&lt;/MyComponent&gt;
</code></pre>
<h2 id="heading-5-scoped-slots">5. Scoped Slots</h2>
<p>Scoped slots allow passing functions or data for more complex slot scenarios:</p>
<pre><code class="lang-bash">&lt;template&gt;
  &lt;ul&gt;
    &lt;li v-for=<span class="hljs-string">"(item, index) in items"</span> :key=<span class="hljs-string">"index"</span>&gt;
      &lt;slot :item=<span class="hljs-string">"item"</span> :index=<span class="hljs-string">"index"</span>&gt;&lt;/slot&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/template&gt;
</code></pre>
<p>Parent component usage:</p>
<pre><code class="lang-bash">&lt;MyList :items=<span class="hljs-string">"list"</span>&gt;
  &lt;template v-slot:default=<span class="hljs-string">"{ item, index }"</span>&gt;
    &lt;span&gt;{{ item.text }} ({{ index }})&lt;/span&gt;
  &lt;/template&gt;
&lt;/MyList&gt;
</code></pre>
<h2 id="heading-6-state-management-vuex-or-pinia">6. State Management (Vuex or Pinia)</h2>
<p>For complex applications, use Vuex or Pinia to centrally manage shared state, enhancing component reusability.</p>
<h2 id="heading-7-higher-order-components-hocs">7. Higher-Order Components (HOCs)</h2>
<p>While Vue.js doesn’t natively support HOCs, you can mimic them using functional components and the Composition API:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withLoading</span>(<span class="hljs-params">ChildComponent</span>) </span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">extends</span>: ChildComponent,
    data() {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">isLoading</span>: <span class="hljs-literal">false</span>,
      };
    },
    <span class="hljs-attr">methods</span>: {
      fetchData() {
        <span class="hljs-built_in">this</span>.isLoading = <span class="hljs-literal">true</span>;
        <span class="hljs-comment">// Data fetching logic</span>
        <span class="hljs-comment">// ...</span>
        <span class="hljs-built_in">this</span>.isLoading = <span class="hljs-literal">false</span>;
      },
    },
  };
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> withLoading(MyComponent);
</code></pre>
<h2 id="heading-8-building-and-publishing-a-component-library">8. Building and Publishing a Component Library</h2>
<p>Building a component library involves tools like Vue CLI, Rollup, or Webpack. Vue CLI offers the <code>vue-cli-service build --library</code> command to create a library. After publishing to npm, other projects can install your library using <code>npm install</code>.</p>
<h2 id="heading-9-component-abstraction-and-encapsulation">9. Component Abstraction and Encapsulation</h2>
<p>To enhance reusability, break components into smaller, focused parts. For example, a form component can be split into input fields, buttons, and validators, each reusable independently or combined into new forms.</p>
<pre><code class="lang-bash">&lt;!-- InputField.vue --&gt;
&lt;template&gt;
  &lt;input :<span class="hljs-built_in">type</span>=<span class="hljs-string">"type"</span> :value=<span class="hljs-string">"value"</span> @input=<span class="hljs-string">"handleChange"</span> :class=<span class="hljs-string">"inputClasses"</span> /&gt;
&lt;/template&gt;

&lt;script&gt;
<span class="hljs-built_in">export</span> default {
  props: {
    <span class="hljs-built_in">type</span>: {
      <span class="hljs-built_in">type</span>: String,
      default: <span class="hljs-string">'text'</span>,
    },
    value: {
      <span class="hljs-built_in">type</span>: [String, Number],
      default: <span class="hljs-string">''</span>,
    },
    inputClasses: {
      <span class="hljs-built_in">type</span>: String,
      default: <span class="hljs-string">''</span>,
    },
  },
  methods: {
    handleChange(event) {
      this.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'input'</span>, event.target.value);
    },
  },
};
&lt;/script&gt;
</code></pre>
<h2 id="heading-10-component-reusability-and-configurability">10. Component Reusability and Configurability</h2>
<p>Design components with configurability in mind, allowing customization via props or slots. For example, a card component can accept properties like background color and border width.</p>
<pre><code class="lang-bash">&lt;!-- Card.vue --&gt;
&lt;template&gt;
  &lt;div :class=<span class="hljs-string">"cardClasses"</span> :style=<span class="hljs-string">"cardStyle"</span>&gt;
    &lt;slot&gt;&lt;/slot&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
<span class="hljs-built_in">export</span> default {
  props: {
    backgroundColor: {
      <span class="hljs-built_in">type</span>: String,
      default: <span class="hljs-string">'#fff'</span>,
    },
    borderColor: {
      <span class="hljs-built_in">type</span>: String,
      default: <span class="hljs-string">'#ccc'</span>,
    },
    borderWidth: {
      <span class="hljs-built_in">type</span>: Number,
      default: 1,
    },
  },
  computed: {
    <span class="hljs-function"><span class="hljs-title">cardClasses</span></span>() {
      <span class="hljs-built_in">return</span> {
        card: <span class="hljs-literal">true</span>,
        // Compute class names based on props
      };
    },
    <span class="hljs-function"><span class="hljs-title">cardStyle</span></span>() {
      <span class="hljs-built_in">return</span> {
        backgroundColor: this.backgroundColor,
        border: `<span class="hljs-variable">${this.borderWidth}</span>px solid <span class="hljs-variable">${this.borderColor}</span>`,
      };
    },
  },
};
&lt;/script&gt;
</code></pre>
<h2 id="heading-11-component-extensibility">11. Component Extensibility</h2>
<p>Design components for future extensibility using slots and events to enable interaction with other components or features. For example, a modal component can include header, content, and footer slots for varied use cases.</p>
<pre><code class="lang-bash">&lt;!-- Modal.vue --&gt;
&lt;template&gt;
  &lt;div class=<span class="hljs-string">"modal"</span> @click=<span class="hljs-string">"handleOutsideClick"</span>&gt;
    &lt;div class=<span class="hljs-string">"modal__content"</span>&gt;
      &lt;slot name=<span class="hljs-string">"header"</span>&gt;&lt;/slot&gt;
      &lt;div class=<span class="hljs-string">"modal__body"</span>&gt;
        &lt;slot&gt;&lt;/slot&gt;
      &lt;/div&gt;
      &lt;slot name=<span class="hljs-string">"footer"</span>&gt;&lt;/slot&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
<span class="hljs-built_in">export</span> default {
  methods: {
    handleOutsideClick(event) {
      <span class="hljs-keyword">if</span> (!this.<span class="hljs-variable">$el</span>.contains(event.target)) {
        this.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'close'</span>);
      }
    },
  },
  <span class="hljs-function"><span class="hljs-title">mounted</span></span>() {
    document.addEventListener(<span class="hljs-string">'mousedown'</span>, this.handleOutsideClick);
  },
  <span class="hljs-function"><span class="hljs-title">beforeDestroy</span></span>() {
    document.removeEventListener(<span class="hljs-string">'mousedown'</span>, this.handleOutsideClick);
  },
};
&lt;/script&gt;
</code></pre>
<h2 id="heading-12-component-documentation-and-examples">12. Component Documentation and Examples</h2>
<p>Write clear documentation covering component purpose, usage examples, props, events, and slots to help developers understand and use your library effectively.</p>
<h2 id="heading-13-testing-and-quality-assurance">13. Testing and Quality Assurance</h2>
<p>Write unit and integration tests to ensure components work correctly in various scenarios, improving reliability by catching and fixing issues during development.</p>
<h2 id="heading-component-lazy-loading">Component Lazy Loading</h2>
<p>Optimize performance with Vue Router’s lazy loading, loading components only when needed, especially for rarely used components in large libraries:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In Vue Router configuration</span>
{
  <span class="hljs-attr">path</span>: <span class="hljs-string">'/some-path'</span>,
  <span class="hljs-attr">component</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/components/SomeLargeComponent.vue'</span>),
},
</code></pre>
<h2 id="heading-on-demand-component-imports">On-Demand Component Imports</h2>
<p>When using third-party libraries, import only needed features with ES modules to avoid loading unnecessary code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { DatePicker } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-datepicker'</span>;
</code></pre>
<h2 id="heading-design-system-and-style-guide">Design System and Style Guide</h2>
<p>Create a design system and style guide defining component styles, interactions, and behaviors to ensure consistency across the library, improving code quality.</p>
<h2 id="heading-version-control-and-release-process">Version Control and Release Process</h2>
<p>Use Git for version control and follow Semantic Versioning (SemVer) for releasing new library versions. Provide detailed changelogs with each release to inform users of changes.</p>
<h2 id="heading-continuous-integrationcontinuous-deployment-cicd">Continuous Integration/Continuous Deployment (CI/CD)</h2>
<p>Set up CI/CD pipelines to automate testing, building, and deploying the component library, ensuring validated commits and rapid production releases.</p>
<h2 id="heading-code-review">Code Review</h2>
<p>Implement code reviews to maintain library quality and consistency, using team audits or platforms like GitHub’s Pull Requests.</p>
<h2 id="heading-feedback-and-improvement">Feedback and Improvement</h2>
<p>Encourage feedback from users and team members to fix issues and enhance the library. Establish a community or forum for users to discuss and share experiences.</p>
<p>By applying these strategies, you can create a robust, efficient, and maintainable Vue component library. Continuously learn and refine component design to meet evolving needs and best practices.</p>
]]></content:encoded></item><item><title><![CDATA[PWA Offline-First Strategies-Key Steps to Enhance User Experience]]></title><description><![CDATA[Progressive Web Apps (PWAs) implement offline-first strategies using Service Workers and the Cache API, enabling access to parts or all of a website’s content without an internet connection.
1. Create a Service Worker File (service-worker.js)
self.ad...]]></description><link>https://tech.tianyaschool.com/pwa-offline-first-strategies-key-steps-to-enhance-user-experience</link><guid isPermaLink="true">https://tech.tianyaschool.com/pwa-offline-first-strategies-key-steps-to-enhance-user-experience</guid><category><![CDATA[PWA]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 18 Aug 2025 13:51:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/hGV2TfOh0ns/upload/8f7e9460998e2cb1c27d8d8f4a03415e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Progressive Web Apps (PWAs) implement offline-first strategies using Service Workers and the Cache API, enabling access to parts or all of a website’s content without an internet connection.</p>
<h2 id="heading-1-create-a-service-worker-file-service-workerjs">1. Create a Service Worker File (service-worker.js)</h2>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'install'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.waitUntil(
    caches.open(<span class="hljs-string">'my-cache-v1'</span>).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> cache.addAll([
        <span class="hljs-string">'/index.html'</span>,
        <span class="hljs-string">'/style.css'</span>,
        <span class="hljs-string">'/script.js'</span>,
        <span class="hljs-comment">// Add other files to precache</span>
      ]);
    })
  );
});

self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.respondWith(
    caches.match(event.request).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (response) {
        <span class="hljs-keyword">return</span> response;
      }
      <span class="hljs-keyword">return</span> fetch(event.request).then(<span class="hljs-function">(<span class="hljs-params">networkResponse</span>) =&gt;</span> {
        caches.open(<span class="hljs-string">'my-cache-v1'</span>).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
          cache.put(event.request.url, networkResponse.clone());
        });
        <span class="hljs-keyword">return</span> networkResponse;
      }).catch(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Return a fallback response, like an error page, if all attempts fail</span>
        <span class="hljs-keyword">return</span> caches.match(<span class="hljs-string">'/offline.html'</span>);
      });
    })
  );
});
</code></pre>
<h2 id="heading-2-register-the-service-worker">2. Register the Service Worker</h2>
<p>Register the Service Worker in your main application:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-string">'serviceWorker'</span> <span class="hljs-keyword">in</span> navigator) {
  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'load'</span>, <span class="hljs-function">() =&gt;</span> {
    navigator.serviceWorker
      .register(<span class="hljs-string">'/service-worker.js'</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">registration</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Service Worker registered:'</span>, registration);
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Service Worker registration failed:'</span>, error);
      });
  });
}
</code></pre>
<h2 id="heading-3-update-strategy">3. Update Strategy</h2>
<p>When a new app version is available, update the Service Worker and cached content by listening to the <code>activate</code> event:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'activate'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.waitUntil(
    caches.keys().then(<span class="hljs-function">(<span class="hljs-params">cacheNames</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.all(
        cacheNames.filter(<span class="hljs-function">(<span class="hljs-params">cacheName</span>) =&gt;</span> cacheName !== <span class="hljs-string">'my-cache-v1'</span>).map(<span class="hljs-function">(<span class="hljs-params">cacheName</span>) =&gt;</span> caches.delete(cacheName))
      );
    })
  );
});
</code></pre>
<h2 id="heading-4-update-the-service-worker">4. Update the Service Worker</h2>
<p>To update the Service Worker, change its filename (e.g., by adding a version number). This signals the browser to treat it as a new Service Worker, triggering the installation process.</p>
<h2 id="heading-5-manage-service-worker-lifecycle">5. Manage Service Worker Lifecycle</h2>
<p>Ensure that updating the Service Worker doesn’t disrupt user experience by allowing the old Service Worker to complete requests before closing:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (event.data &amp;&amp; event.data.type === <span class="hljs-string">'SKIP_WAITING'</span>) {
    self.skipWaiting();
  }
});
</code></pre>
<h2 id="heading-6-configure-the-manifest-file">6. Configure the Manifest File</h2>
<p>Create a <code>manifest.json</code> file to define app metadata and offline icons:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"short_name"</span>: <span class="hljs-string">"My App"</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"My Awesome Progressive Web App"</span>,
  <span class="hljs-attr">"icons"</span>: [
    {
      <span class="hljs-attr">"src"</span>: <span class="hljs-string">"icon-192.png"</span>,
      <span class="hljs-attr">"sizes"</span>: <span class="hljs-string">"192x192"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"image/png"</span>
    },
    {
      <span class="hljs-attr">"src"</span>: <span class="hljs-string">"icon-512.png"</span>,
      <span class="hljs-attr">"sizes"</span>: <span class="hljs-string">"512x512"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"image/png"</span>
    }
  ],
  <span class="hljs-attr">"start_url"</span>: <span class="hljs-string">"/index.html"</span>,
  <span class="hljs-attr">"display"</span>: <span class="hljs-string">"standalone"</span>,
  <span class="hljs-attr">"background_color"</span>: <span class="hljs-string">"#ffffff"</span>,
  <span class="hljs-attr">"theme_color"</span>: <span class="hljs-string">"#000000"</span>
}
</code></pre>
<h3 id="heading-reference-the-manifest-in-html">Reference the Manifest in HTML</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"manifest"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/manifest.json"</span>&gt;</span>
</code></pre>
<h2 id="heading-7-offline-notifications-and-reload-prompts">7. Offline Notifications and Reload Prompts</h2>
<p>Notify users to reload the page for updated content when they regain connectivity:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'online'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  clients.matchAll({ <span class="hljs-attr">type</span>: <span class="hljs-string">'window'</span> }).then(<span class="hljs-function">(<span class="hljs-params">clients</span>) =&gt;</span> {
    clients.forEach(<span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
      client.postMessage({ <span class="hljs-attr">type</span>: <span class="hljs-string">'RELOAD'</span> });
    });
  });
});

self.addEventListener(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (event.data &amp;&amp; event.data.type === <span class="hljs-string">'RELOAD'</span>) {
    clients.matchAll({ <span class="hljs-attr">type</span>: <span class="hljs-string">'window'</span> }).then(<span class="hljs-function">(<span class="hljs-params">clients</span>) =&gt;</span> {
      clients.forEach(<span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (client.url === self.registration.scope &amp;&amp; <span class="hljs-string">'focus'</span> <span class="hljs-keyword">in</span> client) {
          client.focus();
          client.reload();
        }
      });
    });
  }
});
</code></pre>
<h3 id="heading-listen-for-messages-in-the-main-app">Listen for Messages in the Main App</h3>
<pre><code class="lang-javascript">navigator.serviceWorker.addEventListener(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (event.data &amp;&amp; event.data.type === <span class="hljs-string">'RELOAD'</span>) {
    alert(<span class="hljs-string">'Network restored, refresh the page for the latest content.'</span>);
    location.reload();
  }
});
</code></pre>
<h2 id="heading-8-offline-prompts-and-experience">8. Offline Prompts and Experience</h2>
<p>Provide a friendly offline page or prompt when users are offline:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>You're Offline<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please try again later.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Handle this in the Service Worker’s <code>fetch</code> event:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.respondWith(
    caches.match(event.request).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (response) {
        <span class="hljs-keyword">return</span> response;
      }
      <span class="hljs-comment">// Handle failed network requests</span>
      <span class="hljs-keyword">return</span> fetch(event.request).catch(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Return offline page</span>
        <span class="hljs-keyword">return</span> caches.match(<span class="hljs-string">'/offline.html'</span>);
      });
    })
  );
});
</code></pre>
<h2 id="heading-9-update-cache-strategy">9. Update Cache Strategy</h2>
<p>To cache specific resource versions instead of always using the latest, implement version control in the Service Worker:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> CACHE_NAME = <span class="hljs-string">'my-cache-v2'</span>;
<span class="hljs-keyword">const</span> urlsToCache = [
  <span class="hljs-comment">// ...</span>
];

self.addEventListener(<span class="hljs-string">'install'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.waitUntil(
    caches.open(CACHE_NAME).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> cache.addAll(urlsToCache);
    })
  );
});

self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.respondWith(
    caches.match(event.request).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (response) {
        <span class="hljs-keyword">return</span> response;
      }
      <span class="hljs-keyword">return</span> fetch(event.request).then(<span class="hljs-function">(<span class="hljs-params">networkResponse</span>) =&gt;</span> {
        caches.open(CACHE_NAME).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
          cache.put(event.request.url, networkResponse.clone());
        });
        <span class="hljs-keyword">return</span> networkResponse;
      });
    })
  );
});
</code></pre>
<h2 id="heading-10-use-the-app-shell-architecture">10. Use the App Shell Architecture</h2>
<p>The App Shell model is a common PWA design pattern that provides a basic UI framework, loadable even offline. It typically includes non-dynamic content like navigation, headers, and sidebars.</p>
<p>Create an App Shell HTML file (e.g., <code>app-shell.html</code>) with basic layout and styles, then precache it in the Service Worker:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> appShellUrls = [
  <span class="hljs-string">'/app-shell.html'</span>,
  <span class="hljs-string">'/app-style.css'</span>,
  <span class="hljs-comment">// Other App Shell-related resources</span>
];

self.addEventListener(<span class="hljs-string">'install'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.waitUntil(
    caches.open(<span class="hljs-string">'app-shell-cache'</span>).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> cache.addAll(appShellUrls);
    })
  );
});
</code></pre>
<p>Prioritize fetching App Shell resources from cache in the <code>fetch</code> event:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (event.request.mode === <span class="hljs-string">'navigate'</span>) {
    event.respondWith(caches.match(<span class="hljs-string">'/app-shell.html'</span>));
  } <span class="hljs-keyword">else</span> {
    event.respondWith(
      caches.match(event.request).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (response) {
          <span class="hljs-keyword">return</span> response;
        }
        <span class="hljs-keyword">return</span> fetch(event.request);
      })
    );
  }
});
</code></pre>
<h2 id="heading-11-intercept-network-requests-with-service-worker">11. Intercept Network Requests with Service Worker</h2>
<p>Service Workers can intercept specific network requests, like API calls, to return default or cached responses offline for a consistent user experience:</p>
<pre><code class="lang-javascript">self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (event.request.url.startsWith(<span class="hljs-string">'https://api.example.com'</span>)) {
    event.respondWith(
      caches.match(event.request).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (response) {
          <span class="hljs-keyword">return</span> response;
        }
        <span class="hljs-keyword">return</span> fetch(event.request).then(<span class="hljs-function">(<span class="hljs-params">networkResponse</span>) =&gt;</span> {
          caches.open(<span class="hljs-string">'api-cache'</span>).then(<span class="hljs-function">(<span class="hljs-params">cache</span>) =&gt;</span> {
            cache.put(event.request.url, networkResponse.clone());
          });
          <span class="hljs-keyword">return</span> networkResponse;
        });
      })
    );
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Handle other non-API requests</span>
  }
});
</code></pre>
<h2 id="heading-12-integrate-websocket-support">12. Integrate WebSocket Support</h2>
<p>For apps using WebSockets for real-time communication, use the <code>workbox-websocket</code> library to manage WebSocket connections in the Service Worker, ensuring messages are handled offline:</p>
<pre><code class="lang-javascript">importScripts(<span class="hljs-string">'https://unpkg.com/workbox-sw@latest/workbox-sw.js'</span>);
importScripts(<span class="hljs-string">'https://unpkg.com/workbox-websocket@latest/workbox-websocket.js'</span>);

workbox.webSocket.register(<span class="hljs-string">'wss://your-websocket-endpoint.com'</span>, {
  <span class="hljs-attr">onConnect</span>: <span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'WebSocket connected:'</span>, client);
  },
  <span class="hljs-attr">onClose</span>: <span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'WebSocket disconnected:'</span>, client);
  },
});
</code></pre>
<h2 id="heading-13-testing-and-monitoring">13. Testing and Monitoring</h2>
<p>Test your PWA under various network conditions, including 2G, 3G, and offline, using Chrome DevTools’ network simulation. Regularly evaluate performance and offline experience with tools like Lighthouse.</p>
<h2 id="heading-14-summary">14. Summary</h2>
<p>These strategies enable the creation of a highly available PWA with excellent user experience, even in offline or weak network conditions. The goal of a PWA is to deliver a near-native app experience, making continuous optimization and testing critical.</p>
]]></content:encoded></item><item><title><![CDATA[Webpack Bundle Analyzer Deep Analysis and Optimization of Your Bundle]]></title><description><![CDATA[Webpack Bundle Analyzer is a visualization tool that helps you analyze the output files generated by Webpack, identifying which modules consume the most space, enabling targeted optimizations.
Installation
First, install Webpack Bundle Analyzer and W...]]></description><link>https://tech.tianyaschool.com/webpack-bundle-analyzer-deep-analysis-and-optimization-of-your-bundle</link><guid isPermaLink="true">https://tech.tianyaschool.com/webpack-bundle-analyzer-deep-analysis-and-optimization-of-your-bundle</guid><category><![CDATA[webpack]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Thu, 14 Aug 2025 10:23:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/SYTO3xs06fU/upload/4cd3bf9ccc80d7739e2cb6acada5b539.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Webpack Bundle Analyzer is a visualization tool that helps you analyze the output files generated by Webpack, identifying which modules consume the most space, enabling targeted optimizations.</p>
<h2 id="heading-installation">Installation</h2>
<p>First, install Webpack Bundle Analyzer and Webpack:</p>
<pre><code class="lang-bash">npm install webpack webpack-cli --save-dev
npm install webpack-bundle-analyzer --save-dev
</code></pre>
<h2 id="heading-configuring-webpack">Configuring Webpack</h2>
<p>Next, configure your Webpack configuration file (<code>webpack.config.js</code>):</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> BundleAnalyzerPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-bundle-analyzer'</span>).BundleAnalyzerPlugin;

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'bundle.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>),
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> BundleAnalyzerPlugin({
      <span class="hljs-attr">analyzerMode</span>: <span class="hljs-string">'static'</span>,
      <span class="hljs-attr">reportFilename</span>: <span class="hljs-string">'report.html'</span>,
      <span class="hljs-attr">openAnalyzer</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Do not auto-open browser</span>
    }),
  ],
  <span class="hljs-comment">// Other configurations...</span>
};
</code></pre>
<h2 id="heading-generating-the-analysis-report">Generating the Analysis Report</h2>
<p>Run Webpack to generate the analysis report:</p>
<pre><code class="lang-bash">npx webpack --mode production
</code></pre>
<p>This creates a <code>report.html</code> file in the <code>dist</code> directory. Open it to view an interactive chart showing your bundle’s size distribution.</p>
<h2 id="heading-optimization-strategies">Optimization Strategies</h2>
<p>To further optimize your bundle, consider the following strategies:</p>
<h3 id="heading-code-splitting">Code Splitting</h3>
<p>Use the <code>splitChunks</code> configuration to split large libraries or components into separate chunks, loading them only when needed.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">splitChunks</span>: {
      <span class="hljs-attr">chunks</span>: <span class="hljs-string">'all'</span>,
    },
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-tree-shaking">Tree Shaking</h3>
<p>Enable the <code>sideEffects</code> property and ES modules to allow Webpack to remove unused code.</p>
<pre><code class="lang-json"><span class="hljs-comment">// package.json</span>
{
  <span class="hljs-attr">"sideEffects"</span>: <span class="hljs-literal">false</span>
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// Enable ES modules in Webpack config</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.m?js$/</span>,
        resolve: {
          <span class="hljs-attr">fullySpecified</span>: <span class="hljs-literal">false</span>,
        },
      },
    ],
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-using-compression-plugins">Using Compression Plugins</h3>
<p>Use <code>TerserWebpackPlugin</code> or other minification tools to reduce file sizes.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> TerserWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'terser-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">minimize</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">minimizer</span>: [
      <span class="hljs-keyword">new</span> TerserWebpackPlugin(),
    ],
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-loader-optimization">Loader Optimization</h3>
<p>Select appropriate loaders, such as <code>url-loader</code> or <code>file-loader</code>, for static assets, setting thresholds to avoid unnecessary transformations.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|jpg|gif)$/i</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'url-loader'</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">limit</span>: <span class="hljs-number">8192</span>, <span class="hljs-comment">// 8KB</span>
              <span class="hljs-attr">fallback</span>: <span class="hljs-string">'file-loader'</span>,
            },
          },
        ],
      },
    ],
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-module-lazy-loading">Module Lazy Loading</h3>
<p>For large applications, use dynamic imports (<code>import()</code>) to lazy-load modules, loading them only when required.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Before</span>
<span class="hljs-keyword">import</span> SomeBigComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./SomeBigComponent'</span>;

<span class="hljs-comment">// After</span>
<span class="hljs-keyword">const</span> SomeBigComponent = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./SomeBigComponent'</span>);
</code></pre>
<h3 id="heading-code-preheating">Code Preheating</h3>
<p>For frequently used lazy-loaded modules, preheat them to reduce initial load delays.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Preload component at app startup</span>
<span class="hljs-keyword">import</span>(<span class="hljs-string">'./SomeBigComponent'</span>).then(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'SomeBigComponent preloaded'</span>);
});
</code></pre>
<h3 id="heading-extracting-common-chunks">Extracting Common Chunks</h3>
<p>Use <code>optimization.splitChunks</code> to extract shared libraries into separate chunks.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">splitChunks</span>: {
      <span class="hljs-attr">cacheGroups</span>: {
        <span class="hljs-attr">vendors</span>: {
          <span class="hljs-attr">test</span>: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
          priority: <span class="hljs-number">-10</span>,
          <span class="hljs-attr">chunks</span>: <span class="hljs-string">'initial'</span>,
        },
        <span class="hljs-attr">common</span>: {
          <span class="hljs-attr">name</span>: <span class="hljs-string">'common'</span>,
          <span class="hljs-attr">test</span>: <span class="hljs-regexp">/[\\/]src[\\/]/</span>,
          chunks: <span class="hljs-string">'all'</span>,
          <span class="hljs-attr">minChunks</span>: <span class="hljs-number">2</span>,
          <span class="hljs-attr">priority</span>: <span class="hljs-number">-20</span>,
          <span class="hljs-attr">reuseExistingChunk</span>: <span class="hljs-literal">true</span>,
        },
      },
    },
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-using-cdns-for-libraries">Using CDNs for Libraries</h3>
<p>For third-party libraries used across all pages, load them from a CDN to reduce server load and initial load time.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- In HTML template --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.example.com/jquery.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-image-optimization">Image Optimization</h3>
<p>Use <code>image-webpack-loader</code> or <code>sharp</code> to compress and optimize images.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|jpe?g|gif|svg)$/i</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'image-webpack-loader'</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">bypassOnDebug</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// webpack@4 compatibility</span>
              <span class="hljs-attr">mozjpeg</span>: {
                <span class="hljs-attr">progressive</span>: <span class="hljs-literal">true</span>,
                <span class="hljs-attr">quality</span>: <span class="hljs-number">65</span>,
              },
              <span class="hljs-attr">optipng</span>: {
                <span class="hljs-attr">enabled</span>: <span class="hljs-literal">false</span>,
              },
              <span class="hljs-attr">pngquant</span>: {
                <span class="hljs-attr">quality</span>: [<span class="hljs-number">0.65</span>, <span class="hljs-number">0.9</span>],
                <span class="hljs-attr">speed</span>: <span class="hljs-number">4</span>,
              },
              <span class="hljs-attr">gifsicle</span>: {
                <span class="hljs-attr">interlaced</span>: <span class="hljs-literal">false</span>,
              },
              <span class="hljs-attr">webp</span>: {
                <span class="hljs-attr">quality</span>: <span class="hljs-number">75</span>,
              },
            },
          },
        ],
      },
    ],
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-leveraging-caching">Leveraging Caching</h3>
<p>Enable caching to store Webpack compilation results, speeding up subsequent builds.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">cache</span>: {
    <span class="hljs-attr">type</span>: <span class="hljs-string">'filesystem'</span>,
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-avoiding-duplicate-modules">Avoiding Duplicate Modules</h3>
<p>Use <code>Module Federation</code> or <code>externals</code> to prevent duplicating libraries across multiple applications.</p>
<p><strong>Module Federation (Webpack 5+)</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Host App</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">experiments</span>: {
    <span class="hljs-attr">outputModule</span>: <span class="hljs-literal">true</span>,
  },
  <span class="hljs-attr">externals</span>: {
    <span class="hljs-attr">react</span>: <span class="hljs-string">'React'</span>,
    <span class="hljs-string">'react-dom'</span>: <span class="hljs-string">'ReactDOM'</span>,
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> ModuleFederationPlugin({
      <span class="hljs-attr">name</span>: <span class="hljs-string">'host_app'</span>,
      <span class="hljs-attr">remotes</span>: {
        <span class="hljs-attr">remote_app</span>: <span class="hljs-string">'remote_app@http://localhost:3001/remoteEntry.js'</span>,
      },
      <span class="hljs-attr">shared</span>: [<span class="hljs-string">'react'</span>, <span class="hljs-string">'react-dom'</span>],
    }),
  ],
  <span class="hljs-comment">// ...</span>
};

<span class="hljs-comment">// Remote App</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">experiments</span>: {
    <span class="hljs-attr">outputModule</span>: <span class="hljs-literal">true</span>,
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> ModuleFederationPlugin({
      <span class="hljs-attr">name</span>: <span class="hljs-string">'remote_app'</span>,
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'remoteEntry.js'</span>,
      <span class="hljs-attr">exposes</span>: {
        <span class="hljs-string">'./RemoteComponent'</span>: <span class="hljs-string">'./src/RemoteComponent'</span>,
      },
    }),
  ],
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<p><code>externals</code> Configuration</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">externals</span>: {
    <span class="hljs-attr">react</span>: <span class="hljs-string">'React'</span>,
    <span class="hljs-string">'react-dom'</span>: <span class="hljs-string">'ReactDOM'</span>,
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<p>This informs Webpack that these libraries are available globally, avoiding redundant bundling.</p>
<h3 id="heading-using-source-maps">Using Source Maps</h3>
<p>Enable source maps during development for easier debugging.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'cheap-module-source-map'</span>,
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-optimizing-fonts-and-icons">Optimizing Fonts and Icons</h3>
<p>Use <code>url-loader</code> or <code>file-loader</code> with a <code>limit</code> parameter to inline or bundle fonts and icons.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(woff|woff2|eot|ttf|otf|svg)$/</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">'url-loader'</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">limit</span>: <span class="hljs-number">10000</span>,
              <span class="hljs-attr">name</span>: <span class="hljs-string">'[name].[ext]'</span>,
              <span class="hljs-attr">outputPath</span>: <span class="hljs-string">'fonts/'</span>,
            },
          },
        ],
      },
    ],
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-avoiding-global-style-pollution">Avoiding Global Style Pollution</h3>
<p>Use CSS Modules or Scoped CSS to limit CSS scope and prevent style conflicts.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// CSS Modules</span>
<span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">'./styles.module.css'</span>;

<span class="hljs-comment">// Scoped CSS</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>&gt;</span><span class="css">
  <span class="hljs-selector-class">.myClass</span> { <span class="hljs-comment">/* ... */</span> }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span>
</code></pre>
<h3 id="heading-optimizing-html-output">Optimizing HTML Output</h3>
<p>Use <code>HtmlWebpackPlugin</code> to generate optimized HTML templates, automatically injecting Webpack’s scripts and styles.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">'./public/index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-string">'body'</span>, <span class="hljs-comment">// Inject scripts at the bottom of body</span>
    }),
  ],
  <span class="hljs-comment">// ...</span>
};
</code></pre>
<h3 id="heading-using-webpack-dev-server">Using Webpack Dev Server</h3>
<p>Use Webpack Dev Server in development for hot reloading and rapid iteration.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">contentBase</span>: <span class="hljs-string">'./dist'</span>,
    <span class="hljs-attr">hot</span>: <span class="hljs-literal">true</span>,
  },
  <span class="hljs-comment">// ...</span>
};
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Web Accessibility Basics-Building Accessible Front-End Applications]]></title><description><![CDATA[Web Accessibility ensures that websites and applications are equally usable by everyone, including those with visual, auditory, motor, or cognitive impairments. Below are foundational principles and code examples for building accessible front-end app...]]></description><link>https://tech.tianyaschool.com/web-accessibility-basics-building-accessible-front-end-applications</link><guid isPermaLink="true">https://tech.tianyaschool.com/web-accessibility-basics-building-accessible-front-end-applications</guid><category><![CDATA[Web Accessibility]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 04 Aug 2025 15:25:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/9l_326FISzk/upload/ca7e8210bde3b5bec02dff998101cce0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Web Accessibility ensures that websites and applications are equally usable by everyone, including those with visual, auditory, motor, or cognitive impairments. Below are foundational principles and code examples for building accessible front-end applications.</p>
<h2 id="heading-1-text-alternatives-alt-attribute">1. Text Alternatives (alt Attribute)</h2>
<p>Provide descriptive <code>alt</code> attributes for non-text content (e.g., images) to enable screen reader users to understand the content.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"hero.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"A smiling person holding a cup of coffee"</span>&gt;</span>
</code></pre>
<h2 id="heading-2-labels-and-roles-aria-roles">2. Labels and Roles (ARIA Roles)</h2>
<p>Use ARIA (Accessible Rich Internet Applications) roles and attributes to enhance accessibility, especially for complex interactive elements.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Close"</span>&gt;</span>X<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h2 id="heading-3-form-elements">3. Form Elements</h2>
<p>Ensure form elements have clear labels, associating <code>&lt;label&gt;</code> with <code>&lt;input&gt;</code> elements.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span>
</code></pre>
<h2 id="heading-4-keyboard-navigation">4. Keyboard Navigation</h2>
<p>All interactive elements should be navigable via keyboard, following a natural focus order.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#home"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#about"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#contact"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</code></pre>
<h2 id="heading-5-color-contrast">5. Color Contrast</h2>
<p>Ensure sufficient color contrast between text and background, avoiding color as the sole means of conveying information.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Use tools like WCAG Color Contrast Checker */</span>
<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span>; <span class="hljs-comment">/* dark text */</span>
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f8f8f8</span>; <span class="hljs-comment">/* light background, good contrast */</span>
}
</code></pre>
<h2 id="heading-6-visually-hidden-content">6. Visually Hidden Content</h2>
<p>Use a <code>visually-hidden</code> class to hide content visually while keeping it accessible to screen readers.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.visually-hidden</span> {
  <span class="hljs-attribute">position</span>: absolute <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">clip</span>: <span class="hljs-built_in">rect</span>(<span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>) <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">1px</span> <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">1px</span> <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">margin</span>: -<span class="hljs-number">1px</span> <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">overflow</span>: hidden <span class="hljs-meta">!important</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"visually-hidden"</span>&gt;</span>Skip to main content<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  Skip
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h2 id="heading-7-aria-live-regions">7. ARIA Live Regions</h2>
<p>Use the <code>aria-live</code> attribute to notify screen reader users of dynamic page updates.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span> <span class="hljs-attr">aria-atomic</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"notification"</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Dynamic content will be inserted here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h2 id="heading-8-time-sensitive-content">8. Time-Sensitive Content</h2>
<p>Provide deadlines or timers for time-sensitive content.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
  This offer expires in:
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"countdown"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-comment">// Update countdown element content</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-9-touch-device-considerations">9. Touch Device Considerations</h2>
<p>Ensure touch targets are at least 44x44 pixels and avoid overly tight layouts.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.button</span> {
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">44px</span>;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">44px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
}
</code></pre>
<h2 id="heading-10-semantic-coding">10. Semantic Coding</h2>
<p>Use semantic HTML elements like <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;article&gt;</code>, <code>&lt;section&gt;</code>, and <code>&lt;footer&gt;</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Header content --&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Main content --&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Footer content --&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<h2 id="heading-11-visual-indicators">11. Visual Indicators</h2>
<p>Add visual feedback for interactive elements, such as hover, focus, and active states.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.button</span> {
  <span class="hljs-attribute">transition</span>: all <span class="hljs-number">0.3s</span>;
}

<span class="hljs-selector-class">.button</span><span class="hljs-selector-pseudo">:hover</span>,
<span class="hljs-selector-class">.button</span><span class="hljs-selector-pseudo">:focus</span>,
<span class="hljs-selector-class">.button</span><span class="hljs-selector-pseudo">:active</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#333</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}
</code></pre>
<h2 id="heading-12-voice-commands-and-input">12. Voice Commands and Input</h2>
<p>Support voice-controlled devices (e.g., Siri, Google Assistant) by ensuring interfaces are operable via voice commands.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/search"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"search"</span>&gt;</span>Search:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"q"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Voice command: Search..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Go<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h2 id="heading-13-font-and-text-readability">13. Font and Text Readability</h2>
<p>Choose readable fonts with sufficient line height, letter spacing, and font size. Ensure text scaling doesn’t break layouts.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.5</span>;
  <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">0.05em</span>;
  <span class="hljs-attribute">text-rendering</span>: optimizeLegibility;
  <span class="hljs-attribute">-ms-text-size-adjust</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">-webkit-text-size-adjust</span>: <span class="hljs-number">100%</span>;
}
</code></pre>
<h2 id="heading-14-clear-state-for-interactive-elements">14. Clear State for Interactive Elements</h2>
<p>Ensure users know when elements are interactive and their interaction state.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"checkbox"</span>]</span><span class="hljs-selector-pseudo">:checked</span> + <span class="hljs-selector-tag">label</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">content</span>: <span class="hljs-string">'\2713'</span>; <span class="hljs-comment">/* checkmark character */</span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"accept"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"accept"</span>&gt;</span>I accept the terms and conditions<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
</code></pre>
<h2 id="heading-15-colorblind-users">15. Colorblind Users</h2>
<p>Use color contrast checkers to ensure color combinations are friendly for colorblind users.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.colorblind-friendly</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#008080</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}
</code></pre>
<h2 id="heading-16-visual-aids">16. Visual Aids</h2>
<p>Provide visual aids like magnifiers, high-contrast modes, or colorblind simulators.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"toggle-high-contrast"</span>&gt;</span>Toggle High Contrast<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'toggle-high-contrast'</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.body.classList.toggle(<span class="hljs-string">'high-contrast'</span>);
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
  <span class="hljs-selector-class">.high-contrast</span> {
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#000</span>;
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<h2 id="heading-17-screen-reader-compatibility">17. Screen Reader Compatibility</h2>
<p>Ensure all critical information is readable by screen readers, such as table captions and summaries.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">caption</span>&gt;</span>Employee List<span class="hljs-tag">&lt;/<span class="hljs-name">caption</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Position<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Office<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Table rows --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<h2 id="heading-18-responsive-design">18. Responsive Design</h2>
<p>Ensure the website performs well across devices and screen sizes, accommodating various access methods.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">768px</span>) {
  <span class="hljs-comment">/* Mobile-specific styles */</span>
}
</code></pre>
<h2 id="heading-19-video-and-audio-content">19. Video and Audio Content</h2>
<p>Provide captions for videos and transcripts for audio.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">video</span> <span class="hljs-attr">controls</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"movie.mp4"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"video/mp4"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">track</span> <span class="hljs-attr">kind</span>=<span class="hljs-string">"captions"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"movie.vtt"</span> <span class="hljs-attr">srclang</span>=<span class="hljs-string">"en"</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"English"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">video</span>&gt;</span>
</code></pre>
<h2 id="heading-20-regular-testing">20. Regular Testing</h2>
<p>Use automated and manual testing tools (e.g., axe, Pa11y, Lighthouse) to regularly check accessibility and improve based on feedback.</p>
<h2 id="heading-21-image-maps">21. Image Maps</h2>
<p>For images with multiple interactive regions, use image maps to provide clickable areas.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"worldmap.png"</span> <span class="hljs-attr">usemap</span>=<span class="hljs-string">"#worldmap"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"World Map"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">map</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"worldmap"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">area</span> <span class="hljs-attr">shape</span>=<span class="hljs-string">"rect"</span> <span class="hljs-attr">coords</span>=<span class="hljs-string">"0,0,82,126"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"North America"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#na"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">area</span> <span class="hljs-attr">shape</span>=<span class="hljs-string">"circle"</span> <span class="hljs-attr">coords</span>=<span class="hljs-string">"200,100,30"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Europe"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#eu"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">area</span> <span class="hljs-attr">shape</span>=<span class="hljs-string">"poly"</span> <span class="hljs-attr">coords</span>=<span class="hljs-string">"330,50,380,0,450,50,400,100"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Asia"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#as"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">map</span>&gt;</span>
</code></pre>
<h2 id="heading-22-text-to-speech">22. Text-to-Speech</h2>
<p>Offer text-to-speech options to allow users to hear page content.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tts"</span>&gt;</span>Read Aloud<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'tts'</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> textToRead = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'main'</span>).innerText;
    <span class="hljs-keyword">const</span> speech = <span class="hljs-keyword">new</span> SpeechSynthesisUtterance(textToRead);
    <span class="hljs-built_in">window</span>.speechSynthesis.speak(speech);
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-23-error-messages-and-feedback">23. Error Messages and Feedback</h2>
<p>Provide clear error messages and feedback to help users resolve issues.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email-error"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"error"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>).addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    <span class="hljs-keyword">const</span> emailInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'email'</span>);
    <span class="hljs-keyword">const</span> errorSpan = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'email-error'</span>);

    <span class="hljs-keyword">if</span> (!emailInput.checkValidity()) {
      errorSpan.textContent = <span class="hljs-string">'Please enter a valid email address.'</span>;
    } <span class="hljs-keyword">else</span> {
      errorSpan.textContent = <span class="hljs-string">''</span>;
      <span class="hljs-comment">// Submit form or perform other actions</span>
    }
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h2 id="heading-24-focus-management-for-interactive-elements">24. Focus Management for Interactive Elements</h2>
<p>Ensure keyboard focus flows correctly between elements, avoiding skips or duplicates.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> focusableElements = <span class="hljs-string">'a[href], button, input:not([type="hidden"]), textarea, select, iframe, object, embed, [tabindex="0"], [contenteditable]'</span>;
<span class="hljs-keyword">const</span> firstFocusableElement = <span class="hljs-built_in">document</span>.querySelector(focusableElements);

<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (firstFocusableElement) {
    firstFocusableElement.focus();
  }
});

<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'keydown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-keyword">if</span> (event.key === <span class="hljs-string">'Tab'</span>) {
    <span class="hljs-keyword">const</span> lastFocusableElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">`<span class="hljs-subst">${focusableElements}</span>:last-of-type`</span>);
    <span class="hljs-keyword">if</span> (event.shiftKey &amp;&amp; <span class="hljs-built_in">document</span>.activeElement === <span class="hljs-built_in">document</span>.body) {
      lastFocusableElement.focus();
      event.preventDefault();
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!event.shiftKey &amp;&amp; <span class="hljs-built_in">document</span>.activeElement === lastFocusableElement) {
      firstFocusableElement.focus();
      event.preventDefault();
    }
  }
});
</code></pre>
]]></content:encoded></item><item><title><![CDATA[CSS Modules vs. Styled Components-Enhancing CSS Maintainability]]></title><description><![CDATA[CSS Modules and Styled Components are modern solutions in web development for improving CSS maintainability. They address issues with traditional CSS, such as style conflicts, naming conventions, and global scope, through different approaches.
CSS Mo...]]></description><link>https://tech.tianyaschool.com/css-modules-vs-styled-components-enhancing-css-maintainability</link><guid isPermaLink="true">https://tech.tianyaschool.com/css-modules-vs-styled-components-enhancing-css-maintainability</guid><category><![CDATA[CSS]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Mon, 04 Aug 2025 15:19:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/2JIvboGLeho/upload/6d538409865cf3f666ff6bd034269093.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>CSS Modules and Styled Components are modern solutions in web development for improving CSS maintainability. They address issues with traditional CSS, such as style conflicts, naming conventions, and global scope, through different approaches.</p>
<h2 id="heading-css-modules">CSS Modules</h2>
<p>CSS Modules is a modular CSS approach that restricts the scope of CSS selectors to local contexts, preventing global style conflicts. Each CSS file generates unique class names, ensuring their exclusivity.</p>
<h3 id="heading-code-example">Code Example</h3>
<pre><code class="lang-css"><span class="hljs-comment">/* styles.module.css */</span>
<span class="hljs-selector-class">.button</span> {
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">color</span>: white;
}

<span class="hljs-selector-class">.active</span> {
  <span class="hljs-attribute">font-weight</span>: bold;
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">'./styles.module.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.button}</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">styles.button</span>} ${<span class="hljs-attr">styles.active</span>}`}&gt;</span>Active<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p>In this example, <code>styles.button</code> and <code>styles.active</code> are localized class names that do not pollute the global namespace.</p>
<h2 id="heading-styled-components">Styled Components</h2>
<p>Styled Components is a CSS-in-JS library that allows you to define styles directly within JavaScript, tightly coupling styles with components. This approach provides component-level styling, eliminates the need for CSS selectors, and supports dynamic styles and variables.</p>
<h3 id="heading-code-example-1">Code Example</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> styled <span class="hljs-keyword">from</span> <span class="hljs-string">'styled-components'</span>;

<span class="hljs-keyword">const</span> Button = styled.button<span class="hljs-string">`
  background-color: blue;
  color: white;

  &amp;.<span class="hljs-subst">${props =&gt; props.isActive &amp;&amp; <span class="hljs-string">'active'</span>}</span> {
    font-weight: bold;
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">isActive</span>=<span class="hljs-string">{true}</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here, <code>Button</code> is a custom component with styles defined internally, and the <code>isActive</code> prop dynamically applies additional styles.</p>
<h2 id="heading-comparison">Comparison</h2>
<ul>
<li><p><strong>CSS Modules</strong>: Closer to traditional CSS but with local scope and import mechanisms, ideal for developers accustomed to CSS.</p>
</li>
<li><p><strong>Styled Components</strong>: Leverages JavaScript’s capabilities for dynamic styles and componentization, suitable for scenarios requiring complex style logic.</p>
</li>
</ul>
<p>Both enhance code maintainability, and the choice depends on project needs and preferences. CSS Modules is preferable for separating styles and logic, while Styled Components is better for tightly integrating styles with components or needing dynamic styles.</p>
<h2 id="heading-combining-css-modules-and-styled-components">Combining CSS Modules and Styled Components</h2>
<p>In some projects, combining CSS Modules and Styled Components can leverage their respective strengths. This allows you to use CSS Modules for modularity and preprocessor support while employing Styled Components for dynamic styles and componentization.</p>
<h3 id="heading-combined-usage-example">Combined Usage Example</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">'./styles.module.css'</span>;
<span class="hljs-keyword">import</span> styled <span class="hljs-keyword">from</span> <span class="hljs-string">'styled-components'</span>;

<span class="hljs-keyword">const</span> StyledButton = styled.button<span class="hljs-string">`
  background-color: <span class="hljs-subst">${({ theme }</span>) =&gt; theme.colors.primary};
  color: <span class="hljs-subst">${({ theme }</span>) =&gt; theme.colors.white};

  /* Add some general CSS-in-JS styles */
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.button}</span>&gt;</span>Normal Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StyledButton</span>&gt;</span>Styled Button<span class="hljs-tag">&lt;/<span class="hljs-name">StyledButton</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>In this example, CSS Modules handles general styles, while Styled Components creates a complex, dynamic button component. This hybrid approach offers flexibility to adapt to project requirements while utilizing the strengths of both.</p>
<h2 id="heading-css-modules-vs-styled-components-pros-and-cons">CSS Modules vs. Styled Components: Pros and Cons</h2>
<h3 id="heading-css-modules-pros">CSS Modules Pros</h3>
<ul>
<li><p><strong>Prevents Global Style Conflicts</strong>: Localized class names avoid naming collisions.</p>
</li>
<li><p><strong>Easy to Understand</strong>: Low learning curve for developers familiar with CSS.</p>
</li>
<li><p><strong>CSS Tool Support</strong>: Compatible with existing CSS preprocessors (e.g., Sass, Less).</p>
</li>
<li><p><strong>Better Modularity</strong>: Each CSS file focuses on a single component’s styles.</p>
</li>
</ul>
<h3 id="heading-css-modules-cons">CSS Modules Cons</h3>
<ul>
<li><p><strong>Manual Style Management</strong>: May require writing more CSS code.</p>
</li>
<li><p><strong>Limited Style Nesting</strong>: While preprocessors can be used, CSS Modules lacks native CSS nesting support.</p>
</li>
<li><p><strong>Less Obvious Style Association</strong>: Class name references in JavaScript may be less intuitive than CSS code.</p>
</li>
</ul>
<h3 id="heading-styled-components-pros">Styled Components Pros</h3>
<ul>
<li><p><strong>Tight Coupling with Components</strong>: Styles and components are defined together, easing maintenance.</p>
</li>
<li><p><strong>Dynamic Styles</strong>: Styles can be based on component props or state.</p>
</li>
<li><p><strong>Full CSS Capabilities</strong>: Supports CSS properties, selectors, variables, and media queries.</p>
</li>
<li><p><strong>Easy Composition</strong>: Enables reusable style components.</p>
</li>
</ul>
<h3 id="heading-styled-components-cons">Styled Components Cons</h3>
<ul>
<li><p><strong>Learning Curve</strong>: May take time for developers unfamiliar with CSS-in-JS to adapt.</p>
</li>
<li><p><strong>Increased JS Overhead</strong>: Styles in JavaScript can lead to larger bundle sizes.</p>
</li>
<li><p><strong>Complex Debugging</strong>: Browser debugging may be challenging, requiring developer tools.</p>
</li>
</ul>
<h2 id="heading-integration-tools-and-best-practices">Integration Tools and Best Practices</h2>
<p>Integrating CSS Modules and Styled Components with build tools (e.g., Webpack, Vite), preprocessors (e.g., Sass, Less), and other CSS-in-JS libraries (e.g., Emotion, JSS) is common in projects. Below are integration and best practice recommendations:</p>
<h3 id="heading-webpack-configuration">Webpack Configuration</h3>
<ul>
<li><p><strong>CSS Modules</strong>: Use <code>css-loader</code> with the <code>modules</code> option set to <code>true</code>.</p>
</li>
<li><p><strong>Styled Components</strong>: Install <code>styled-components</code> and ensure Babel is configured to handle JSX and CSS-in-JS syntax.</p>
</li>
</ul>
<h3 id="heading-preprocessor-integration">Preprocessor Integration</h3>
<ul>
<li><p>Use <code>sass-loader</code> or <code>less-loader</code> with corresponding preprocessor libraries.</p>
</li>
<li><p>For CSS Modules, configure preprocessors using <code>.module.scss</code> or <code>.module.less</code> as file extensions for modular CSS.</p>
</li>
</ul>
<h3 id="heading-theme-support">Theme Support</h3>
<ul>
<li><p>Use <code>styled-components</code>’ <code>ThemeProvider</code> to pass theme objects for access in components.</p>
</li>
<li><p>For CSS Modules, define theme variables in a global CSS file, then import and use them in components.</p>
</li>
</ul>
<h3 id="heading-code-splitting-and-on-demand-loading">Code Splitting and On-Demand Loading</h3>
<ul>
<li>Use Webpack’s <code>SplitChunksPlugin</code> or Vite’s dynamic imports to reduce initial load times.</li>
</ul>
<h3 id="heading-style-consistency">Style Consistency</h3>
<ul>
<li><p>Employ CSS Lint or Stylelint to maintain consistent and high-quality style code.</p>
</li>
<li><p>Follow CSS naming conventions like BEM (Block Element Modifier) or Atomic CSS.</p>
</li>
</ul>
<h3 id="heading-testing">Testing</h3>
<ul>
<li>Use <code>jest-styled-components</code> or <code>testing-library/styled-components</code> to ensure correct component styling.</li>
</ul>
<h3 id="heading-performance-optimization">Performance Optimization</h3>
<ul>
<li><p>Leverage performance optimization options from CSS-in-JS libraries, such as <code>shouldComponentUpdate</code> or <code>@emotion/cache</code>.</p>
</li>
<li><p>For CSS Modules, extract common CSS to reduce network requests.</p>
</li>
</ul>
<h3 id="heading-documentation-and-code-style">Documentation and Code Style</h3>
<ul>
<li>Create clear documentation and coding standards to guide the team on using and organizing CSS Modules and Styled Components.</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>Choosing CSS Modules, Styled Components, or a combination depends on project characteristics, team preferences, and proficiency with CSS and JavaScript. The key is to find a solution that meets project needs while enhancing code maintainability. Ensure the team has sufficient understanding and proficiency with the chosen technology to support long-term development and maintenance.</p>
]]></content:encoded></item><item><title><![CDATA[Front-End Framework Selection Guide-React vs Vue vs Angular]]></title><description><![CDATA[When choosing a front-end framework, React, Vue, and Angular are popular options, each with its strengths and weaknesses. This guide compares them across various dimensions to aid in decision-making.
React

Core Philosophy: Component-based developmen...]]></description><link>https://tech.tianyaschool.com/front-end-framework-selection-guide-react-vs-vue-vs-angular</link><guid isPermaLink="true">https://tech.tianyaschool.com/front-end-framework-selection-guide-react-vs-vue-vs-angular</guid><category><![CDATA[Frontend Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Sat, 02 Aug 2025 11:12:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/3GZNPBLImWc/upload/03d4636d0f601e19b2633d397339d489.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When choosing a front-end framework, React, Vue, and Angular are popular options, each with its strengths and weaknesses. This guide compares them across various dimensions to aid in decision-making.</p>
<h2 id="heading-react">React</h2>
<ul>
<li><p><strong>Core Philosophy</strong>: Component-based development, focused on the view layer.</p>
</li>
<li><p><strong>Learning Curve</strong>: Relatively gentle, emphasizing JSX and component logic.</p>
</li>
<li><p><strong>Ecosystem</strong>: Extremely rich, with numerous third-party libraries and tools.</p>
</li>
<li><p><strong>Performance</strong>: Utilizes virtual DOM for optimized performance.</p>
</li>
<li><p><strong>Template Syntax</strong>: Uses JSX, closely aligned with JavaScript syntax.</p>
</li>
<li><p><strong>State Management</strong>: Common solutions include Redux and MobX.</p>
</li>
<li><p><strong>Best For</strong>: Medium to large projects, especially for teams with a strong JavaScript foundation.</p>
</li>
</ul>
<h2 id="heading-vue">Vue</h2>
<ul>
<li><p><strong>Core Philosophy</strong>: Simpler and beginner-friendly, offering a comprehensive solution.</p>
</li>
<li><p><strong>Learning Curve</strong>: Low, with clear and detailed documentation.</p>
</li>
<li><p><strong>Ecosystem</strong>: Rapidly growing, with broad support.</p>
</li>
<li><p><strong>Performance</strong>: Uses virtual DOM and optimization strategies.</p>
</li>
<li><p><strong>Template Syntax</strong>: Has its own template system, easy to read.</p>
</li>
<li><p><strong>State Management</strong>: Built-in Vuex for complete state management.</p>
</li>
<li><p><strong>Best For</strong>: Small to medium projects, rapid prototyping, or teams needing quick onboarding.</p>
</li>
</ul>
<h2 id="heading-angular">Angular</h2>
<ul>
<li><p><strong>Core Philosophy</strong>: Full-stack framework with an MVC architecture.</p>
</li>
<li><p><strong>Learning Curve</strong>: Steeper, due to its extensive concepts and tools.</p>
</li>
<li><p><strong>Ecosystem</strong>: Comprehensive and robust, backed by Google.</p>
</li>
<li><p><strong>Performance</strong>: Uses change detection, configurable for optimization.</p>
</li>
<li><p><strong>Template Syntax</strong>: Own template system with two-way data binding support.</p>
</li>
<li><p><strong>State Management</strong>: Offers libraries like NgRx for state management.</p>
</li>
<li><p><strong>Best For</strong>: Large-scale enterprise projects requiring strict structure and standards.</p>
</li>
</ul>
<h2 id="heading-development-efficiency">Development Efficiency</h2>
<ul>
<li><p><strong>React</strong>: Requires manual handling of state management and routing but offers a wide range of third-party libraries like Redux and React Router.</p>
</li>
<li><p><strong>Vue</strong>: Provides a complete CLI tool with built-in state and routing management, enabling faster development.</p>
</li>
<li><p><strong>Angular</strong>: Offers a comprehensive solution, including CLI tools, but its steeper learning curve can slow initial progress.</p>
</li>
</ul>
<h2 id="heading-performance-optimization">Performance Optimization</h2>
<ul>
<li><p><strong>React</strong>: Optimizes performance via virtual DOM, <code>shouldComponentUpdate</code>, and <code>PureComponent</code>.</p>
</li>
<li><p><strong>Vue</strong>: Features similar optimization mechanisms, such as component caching and computed property caching.</p>
</li>
<li><p><strong>Angular</strong>: Provides change detection strategies like <code>OnPush</code> for optimization.</p>
</li>
</ul>
<h2 id="heading-community-and-ecosystem">Community and Ecosystem</h2>
<ul>
<li><p><strong>React</strong>: Massive community with numerous open-source libraries, such as Material-UI and Ant Design.</p>
</li>
<li><p><strong>Vue</strong>: Active community with excellent UI libraries like Element UI and Vuetify.</p>
</li>
<li><p><strong>Angular</strong>: Smaller community but supported by Google, with official libraries like Angular Material.</p>
</li>
</ul>
<h2 id="heading-scalability-and-maintainability">Scalability and Maintainability</h2>
<ul>
<li><p><strong>React</strong>: Component-based design facilitates splitting and reuse but requires good architectural planning.</p>
</li>
<li><p><strong>Vue</strong>: Emphasizes componentization and out-of-the-box solutions, making maintenance easier.</p>
</li>
<li><p><strong>Angular</strong>: Strict architecture and modularity suit large projects, though excessive complexity can increase learning costs.</p>
</li>
</ul>
<h2 id="heading-enterprise-support">Enterprise Support</h2>
<ul>
<li><p><strong>React</strong>: Open-source project by Facebook, widely used across various companies.</p>
</li>
<li><p><strong>Vue</strong>: Started as an individual project but adopted by major companies like Alibaba.</p>
</li>
<li><p><strong>Angular</strong>: Google’s product, commonly used in enterprise applications.</p>
</li>
</ul>
<h2 id="heading-learning-curve">Learning Curve</h2>
<ul>
<li><p><strong>React</strong>: Requires understanding JSX and React Hooks, but basic JavaScript knowledge is sufficient.</p>
</li>
<li><p><strong>Vue</strong>: Simple to learn with clear documentation, ideal for beginners.</p>
</li>
<li><p><strong>Angular</strong>: Involves more concepts like dependency injection and directives, resulting in a steeper learning curve.</p>
</li>
</ul>
<h2 id="heading-framework-portability">Framework Portability</h2>
<ul>
<li><p><strong>React</strong>: Its component-based design and JSX flexibility make React components easily integrable with other libraries and frameworks like Gatsby and Next.js.</p>
</li>
<li><p><strong>Vue</strong>: Vue components can also integrate with libraries like Nuxt.js and Quasar Framework. Vue 3’s Composition API enhances portability.</p>
</li>
<li><p><strong>Angular</strong>: Due to its full-stack nature, Angular projects are harder to migrate to other frameworks, but Angular Elements enables Web Components for some cross-framework compatibility.</p>
</li>
</ul>
<h2 id="heading-internationalization-i18n">Internationalization (i18n)</h2>
<ul>
<li><p><strong>React</strong>: Uses libraries like <code>i18next</code> or <code>react-intl</code>, requiring manual configuration.</p>
</li>
<li><p><strong>Vue</strong>: Offers <code>vue-i18n</code> for convenient internationalization support.</p>
</li>
<li><p><strong>Angular</strong>: Provides built-in i18n support with <code>ng serve --i18n</code>, <code>ng xi18n</code>, and Angular’s i18n toolchain.</p>
</li>
</ul>
<h2 id="heading-testing">Testing</h2>
<ul>
<li><p><strong>React</strong>: Uses tools like Jest and Enzyme for unit and integration testing.</p>
</li>
<li><p><strong>Vue</strong>: Provides <code>vue-test-utils</code>, compatible with testing frameworks like Jest and Mocha.</p>
</li>
<li><p><strong>Angular</strong>: Offers Angular CLI testing tools like Karma and Jasmine, plus Protractor for end-to-end testing.</p>
</li>
</ul>
<h2 id="heading-choosing-the-right-framework">Choosing the Right Framework</h2>
<p>The choice of framework depends on project requirements, team skill sets, project scale, and long-term maintenance considerations. For example:</p>
<ul>
<li><p><strong>React</strong>: Ideal for teams familiar with JavaScript seeking rapid iteration.</p>
</li>
<li><p><strong>Vue</strong>: Easier for new developers, suitable for fast development.</p>
</li>
<li><p><strong>Angular</strong>: Best for teams needing a complete solution with routing, state management, and services.</p>
</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>There’s no absolute “best” choice among React, Vue, and Angular; each has unique strengths and ideal use cases. React suits projects requiring high customization and flexibility, Vue is great for rapid development and maintenance, and Angular excels in large, structured enterprise applications. When deciding, consider project needs, team technical expertise, long-term maintenance, and scalability.</p>
]]></content:encoded></item><item><title><![CDATA[React Suspense and Concurrent Mode-The Future of Asynchronous Rendering]]></title><description><![CDATA[React’s Suspense and Concurrent Mode, introduced in React 16.8 and later, aim to enhance user experience and performance, particularly for asynchronous data loading and animations. They are part of React’s next-generation rendering strategies, design...]]></description><link>https://tech.tianyaschool.com/react-suspense-and-concurrent-mode-the-future-of-asynchronous-rendering</link><guid isPermaLink="true">https://tech.tianyaschool.com/react-suspense-and-concurrent-mode-the-future-of-asynchronous-rendering</guid><category><![CDATA[React]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[javascript framework]]></category><dc:creator><![CDATA[Tianya School]]></dc:creator><pubDate>Sat, 02 Aug 2025 11:10:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cckf4TsHAuw/upload/310ce6209d0ba0a7d2f0310abe92c9ad.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>React’s Suspense and Concurrent Mode, introduced in React 16.8 and later, aim to enhance user experience and performance, particularly for asynchronous data loading and animations. They are part of React’s next-generation rendering strategies, designed to deliver smoother interactions and more efficient resource scheduling.</p>
<h2 id="heading-suspense">Suspense</h2>
<p><code>Suspense</code> is a component that allows you to designate an area where components may load asynchronously. When the data for these components isn’t ready, <code>Suspense</code> displays a placeholder (fallback) until the data is available, then renders the component. Here’s a simple example:</p>
<h3 id="heading-purpose">Purpose</h3>
<p>Suspense primarily addresses asynchronous data loading during component rendering, enabling components to wait for their dependencies to be ready before rendering, rather than showing incomplete placeholders or error messages.</p>
<h3 id="heading-how-it-works">How It Works</h3>
<ul>
<li><p><strong>Asynchronous Boundary</strong>: The <code>Suspense</code> component acts as a boundary, wrapping child components that may need to wait for data to load.</p>
</li>
<li><p><strong>Fallback UI</strong>: During the wait, Suspense uses a <code>fallback</code> prop to display a loading indicator or other placeholder content.</p>
</li>
<li><p><strong>Data Preloading</strong>: Combined with <code>React.lazy</code>, it enables lazy loading of components, automatically triggering their load on first render.</p>
</li>
<li><p><strong>Data Loading Coordination</strong>: Paired with React’s Context API and hooks (e.g., <code>useSuspenseResource</code>), it provides fine-grained control over data loading.</p>
</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useEffect, lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { fetchSomeData } <span class="hljs-keyword">from</span> <span class="hljs-string">'./asyncDataFetch'</span>; <span class="hljs-comment">// Asynchronous data fetch function</span>

<span class="hljs-keyword">const</span> AsyncComponent = lazy(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    fetchSomeData().then(<span class="hljs-function">() =&gt;</span> resolve(<span class="hljs-keyword">import</span>(<span class="hljs-string">'./AsyncComponent'</span>)));
  });
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [dataReady, setDataReady] = useState(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchSomeData().then(<span class="hljs-function">() =&gt;</span> setDataReady(<span class="hljs-literal">true</span>));
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {dataReady ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">AsyncComponent</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
      ) : null}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In this code, <code>AsyncComponent</code> is lazily loaded. It renders only when <code>fetchSomeData</code> completes and <code>dataReady</code> is set to <code>true</code>; otherwise, a “Loading…” placeholder is shown.</p>
<h2 id="heading-concurrent-mode">Concurrent Mode</h2>
<p><code>Concurrent Mode</code> is a rendering strategy that allows React to pause and resume rendering without interrupting the user interface. By intelligently scheduling tasks, it optimizes user experience, such as pausing background content loading to prioritize rendering visible parts during user interactions like scrolling.</p>
<h3 id="heading-purpose-1">Purpose</h3>
<p>Concurrent Mode enhances application responsiveness and interaction smoothness through concurrent rendering and intelligent scheduling. It allows React to use idle time efficiently for UI updates while ensuring immediate responses to high-priority tasks.</p>
<h3 id="heading-core-concepts">Core Concepts</h3>
<ul>
<li><p><strong>Concurrent Rendering</strong>: Enables multiple rendering tasks to run simultaneously, allowing React to pause low-priority renders for user inputs or high-priority updates.</p>
</li>
<li><p><strong>Time Slicing</strong>: Breaks complex rendering tasks into smaller chunks, executed incrementally to avoid blocking the main thread.</p>
</li>
<li><p><strong>Priority Scheduling</strong>: React assigns rendering priorities based on task urgency (e.g., user interactions).</p>
</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useEffect, startTransition } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-number">0</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    startTransition(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// Code here runs in a concurrent task, not blocking UI updates</span>
      setValue(value + <span class="hljs-number">1</span>);
    });
  }, [value]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{value}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In this example, <code>startTransition</code> places the code in a low-priority task, ensuring it doesn’t block ongoing UI updates even if it takes time to execute.</p>
<h2 id="heading-combining-suspense-and-concurrent-mode">Combining Suspense and Concurrent Mode</h2>
<p><code>Suspense</code> and <code>Concurrent Mode</code> are often used together to create smoother application experiences, allowing asynchronous operations to proceed without interrupting the UI.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useEffect, startTransition, lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { fetchSomeData } <span class="hljs-keyword">from</span> <span class="hljs-string">'./asyncDataFetch'</span>; <span class="hljs-comment">// Asynchronous data fetch function</span>

<span class="hljs-keyword">const</span> AsyncComponent = lazy(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    fetchSomeData().then(<span class="hljs-function">() =&gt;</span> resolve(<span class="hljs-keyword">import</span>(<span class="hljs-string">'./AsyncComponent'</span>)));
  });
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [dataReady, setDataReady] = useState(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    startTransition(<span class="hljs-function">() =&gt;</span> {
      fetchSomeData().then(<span class="hljs-function">() =&gt;</span> setDataReady(<span class="hljs-literal">true</span>));
    });
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {dataReady ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">AsyncComponent</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
      ) : null}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p><code>startTransition</code> ensures data loading doesn’t block the UI, while <code>Suspense</code> displays a loading indicator until the data is ready. Together, they provide a seamless user experience even during asynchronous data and component loading.</p>
<h2 id="heading-practical-benefits">Practical Benefits</h2>
<h3 id="heading-1-efficient-resource-loading-and-rendering">1. Efficient Resource Loading and Rendering</h3>
<ul>
<li><p><strong>Lazy Loading</strong>: Using <code>React.lazy</code> and <code>Suspense</code>, components can be loaded on-demand, reducing initial load times and improving user experience.</p>
</li>
<li><p><strong>Data Preloading</strong>: Preload data before users reach a page or state, minimizing wait times during interactions.</p>
</li>
</ul>
<h3 id="heading-2-graceful-error-handling">2. Graceful Error Handling</h3>
<ul>
<li><strong>Unified Error Display</strong>: Combine Error Boundaries with Suspense’s error handling to manage errors during component loading or data fetching consistently.</li>
</ul>
<h3 id="heading-3-dynamic-priority-adjustment">3. Dynamic Priority Adjustment</h3>
<ul>
<li><strong>Adaptive User Experience</strong>: Concurrent Mode allows React to adjust rendering task priorities based on the runtime environment (e.g., device performance, user interaction state) for optimal performance.</li>
</ul>
<h3 id="heading-4-simplified-state-management">4. Simplified State Management</h3>
<ul>
<li><strong>Seamless Integration with State Libraries</strong>: When used with MobX, Redux, or React’s Context API, Suspense and Concurrent Mode streamline asynchronous state updates, reducing synchronization complexity.</li>
</ul>
<h3 id="heading-5-future-scalability">5. Future Scalability</h3>
<ul>
<li><strong>Framework-Level Support</strong>: As React evolves, Suspense and Concurrent Mode will unlock further potential, such as improved support for server-side rendering (SSR) and client-side rendering (CSR), plus a broader API set for flexible rendering logic control.</li>
</ul>
<h2 id="heading-complete-example-of-suspense-and-concurrent-mode">Complete Example of Suspense and Concurrent Mode</h2>
<h3 id="heading-install-required-libraries">Install Required Libraries</h3>
<pre><code class="lang-bash">npm install axios react-spring react-dom
</code></pre>
<p>Create a simple component that displays an animation after data loading:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { lazy, Suspense, useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useSpring, animated } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-spring'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> LazyAnimatedComponent = lazy(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve(<span class="hljs-keyword">import</span>(<span class="hljs-string">'./LazyAnimatedComponent'</span>));
    }, <span class="hljs-number">2000</span>); <span class="hljs-comment">// Simulate async loading delay</span>
  });
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [isLoaded, setIsLoaded] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> fadeInProps = useSpring({ <span class="hljs-attr">opacity</span>: isLoaded ? <span class="hljs-number">1</span> : <span class="hljs-number">0</span> });

  useEffect(<span class="hljs-function">() =&gt;</span> {
    axios.get(<span class="hljs-string">'https://api.example.com/data'</span>).then(<span class="hljs-function">() =&gt;</span> {
      setIsLoaded(<span class="hljs-literal">true</span>);
    });
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">animated.div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{fadeInProps}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">LazyAnimatedComponent</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">animated.div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In <code>LazyAnimatedComponent</code>, add animation effects, such as a fade-in:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { animated, useSpring } <span class="hljs-keyword">from</span> <span class="hljs-string">'react spring'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">LazyAnimatedComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> fadeInProps = useSpring({ <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span> });

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">animated.div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{fadeInProps}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is an animated lazy-loaded component.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">animated.div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LazyAnimatedComponent;
</code></pre>
<p>To fully leverage <code>Concurrent Mode</code>, enable it in the ReactDOM rendering method, typically at the entry point for server-side and client-side rendering:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom/client'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;

<span class="hljs-comment">// Client-side rendering</span>
<span class="hljs-keyword">const</span> root = ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));
root.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>);
</code></pre>
<p>In this example, we check for server-side rendered HTML and use <code>createRoot</code> for client-side rendering. This approach ensures <code>Suspense</code> and <code>Concurrent Mode</code> benefits are utilized even with server-side rendering.</p>
]]></content:encoded></item></channel></rss>