Web Programming Post Tag - TechOpt.io https://www.techopt.io/tag/web-programming Programming, servers, Linux, Windows, macOS & more Sat, 12 Jul 2025 21:40:27 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 https://www.techopt.io/wp-content/uploads/2024/07/cropped-logo-1-32x32.png Web Programming Post Tag - TechOpt.io https://www.techopt.io/tag/web-programming 32 32 Solving Next.js dynamic() Flicker with React.lazy https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy#respond Sat, 12 Jul 2025 21:40:24 +0000 https://www.techopt.io/?p=1039 If you’re working with the Next.js App Router and using the dynamic() function for component-level code splitting, you may have encountered an annoying issue: flickering during rendering of a conditionally-rendered dynamic component. Unfortunately, this is a known issue with the App Router and the dynamic function in Next.js. This behavior can degrade user experience, so […]

The post Solving Next.js dynamic() Flicker with React.lazy appeared first on TechOpt.

]]>
If you’re working with the Next.js App Router and using the dynamic() function for component-level code splitting, you may have encountered an annoying issue: flickering during rendering of a conditionally-rendered dynamic component. Unfortunately, this is a known issue with the App Router and the dynamic function in Next.js. This behavior can degrade user experience, so solving the Next.js dynamic flicker on your website is crucial.

In this post, I’ll break down:

  • Why next/dynamic causes flickering
  • Why it’s worse with nested dynamic components
  • When dynamic() is still safe to use
  • A practical alternative using React.lazy() and Suspense
  • What trade-offs to expect when switching

The Flickering Problem in Next.js

Using dynamic() from next/dynamic is a great way to lazy-load components and reduce your JavaScript bundle size. It also supports options like { ssr: false } to only load components on the client side.

However, when you use these components with the App Router, they often cause a flash of missing or unstyled content, especially during fast navigation or when conditionally rendering dynamic components.

Nested dynamic() calls tend to amplify this issue. For example, a parent component conditionally loading a child via dynamic(), which in turn loads another sub-component dynamically, can make the flickering more severe.

This issue has been reported in GitHub issues and community threads, but a rock-solid fix hasn’t yet made it into the framework.

Interestingly, this flicker seems to affect nested dynamic components more than top-level ones. In my testing, first-level dynamically rendered components used directly in the page file rarely exhibit the issue, which means it’s generally safe to use next/dynamic there to avoid flash of unstyled content (FOUC) during initial mount.

The Better Alternative: React.lazy() + Suspense

One workaround that has proven effective is switching from next/dynamic to native React.lazy() with Suspense. This approach introduces fewer hydration inconsistencies and minimizes flickering, even with nested lazy-loaded components.

Use next/dynamic for components initially rendered on the page, and use React.lazy() for nested components that are rendered conditionally inside those components.

Example 1: Top-level safe usage with next/dynamic

import dynamic from 'next/dynamic';
import { isSignedInAsync } from '../auth';

const PageShell = dynamic(() => import('../components/PageShell'));

export default async function Home() {
  const isSignedIn = await isSignedInAsync();

  if (isSignedIn) return null;

  return <PageShell />;
}

In this example, PageShell is conditionally rendered on the server using dynamic components. This is safe since the dynamic component is rendered with the initial HTML from the server.

Example 2: Nesting with React.lazy() and Suspense

"use client";
import dynamic from 'next/dynamic';

const NestedComponent = dynamic(() => import('./NestedComponent'));

export default function PageShell() {
  const [showNested, setShowNested] = useState(false);

  return (
    <div>
      <h1>Welcome</h1>
      <button onClick={() => setShowNested(true)}>Load Nested Component</button>
      {showNested && (
        <Suspense fallback={<div>Loading nested...</div>}>
          <NestedComponent />
        </Suspense>
      )}
    </div>
  );
}

We can safely use React.lazy() and Suspense inside our dynamically-rendered PageShell component to conditionally render our NestedComponent, and still benefit from lazy-loading and code-splitting.

If we try using the dynamic function instead of React.lazy here, we may get the Next.js dynamic flicker.

Trade-offs of Using React.lazy() Instead of dynamic

While React.lazy() and Suspense often result in smoother rendering, there are two notable downsides:

1. No Server-Side Rendering

Unlike next/dynamic, which lets you disable or enable SSR, React.lazy() only supports client-side rendering. This might hurt SEO if your component needs to be visible to crawlers.

2. Flash of Unstyled Content (FOUC) on Mount

If you do try to use React.lazy() for SSR and use it in the server-rendered HTML, React.lazy() may cause a brief flash of unstyled content because the Next.js bundler doesn’t automatically include the styles for components loaded through React.lazy() in the server-rendered HTML. This limitation can lead to inconsistent rendering.

This is why it’s best to use next/dynamic for components that are visible in the server-rendered HTML, ensuring that styles and structure are present at first paint, while reserving React.lazy() for non-critical or nested components. Using next/dynamic in the initial server-rendered HTML does not seem to cause flickering.

Final Thoughts on Preventing the Next.js Dynamic Flicker

If you’re seeing flickering with next/dynamic and conditional rendering, especially in complex nested layouts, you’re not alone. While the Next.js team continues to evolve App Router, switching to React.lazy() and Suspense where you can may provide a smoother user experience at this time.

To summarize:

  • Use next/dynamic safely for top-level page components
  • Use React.lazy() for nested dynamic imports to reduce flicker

The post Solving Next.js dynamic() Flicker with React.lazy appeared first on TechOpt.

]]>
https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy/feed 0
React Conditional Rendering: Logical AND vs Ternary Operator https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator#respond Tue, 01 Apr 2025 22:30:57 +0000 https://www.techopt.io/?p=877 After building countless React and React Native components, I’ve run into one too many frustrating bugs caused by the logical AND (&&) operator used for conditional rendering in JSX. These issues are often subtle and hard to track down, so I’ve made it a rule: I don’t use logical AND for conditional rendering in JSX […]

The post React Conditional Rendering: Logical AND vs Ternary Operator appeared first on TechOpt.

]]>
After building countless React and React Native components, I’ve run into one too many frustrating bugs caused by the logical AND (&&) operator used for conditional rendering in JSX. These issues are often subtle and hard to track down, so I’ve made it a rule: I don’t use logical AND for conditional rendering in JSX anymore. Instead, I stick with the ternary (conditional) operator (in other words, shorthand “if” statement). It’s safer, clearer, and avoids nasty surprises.

The Problem with Logical AND for Conditional Rendering

Here’s a typical use case with logical AND:

{user.age && <Text>{`Age: ${user.age}`}</Text>}

You might expect this to only render the Text element if user.age is defined, or above 0 (since 0 is a falsy value in JavaScript).

But consider what happens if user.age is 0 (a valid, real-world age). We don’t want the <Text> element to get rendered in this case, and it doesn’t.

However, it creates a pretty unwanted side effect:

  • 0 && <Text>...</Text> evaluates to 0.
  • React will render the value 0 directly, essentially interpreting it as text instead of a boolean value!
    • In React Native, this is even worse: it will actually crash the entire application with an error about trying to render text outside of a <Text> component!

Example:

const user = { age: 0 };

return (
  <View>
    {user.age && <Text>{`Age: ${user.age}`}</Text>}
  </View>
);

What renders: Just 0. Not the <Text> element.

This happens because && doesn’t enforce a boolean context; it returns the first falsy value or the last truthy value. That means non-boolean values like 0 or "" can sneak through and show up unexpectedly. This can also crash your entire application in the case of React Native!

A Better Alternative: The Ternary Operator (Shorthand “if” Statements)

Instead, I use the ternary (conditional) operator, which makes the intent clearer and avoids rendering unwanted values:

{user.age ? <Text>{`Age: ${user.age}`}</Text> : null}

This guarantees that only a JSX element or null will be rendered; no accidental numbers or strings appearing in your layout.

Improved Example:

const user = { age: 0 };

return (
  <View>
    {user.age ? <Text>{`Age: ${user.age}`}</Text> : null}
  </View>
);

What renders: Nothing if age is undefined, null or 0, and the full Text block if it’s any other number.

Summary: Use the Ternary Operator for Conditional Rendering in React

While using && for conditional rendering may seem like a shortcut, it’s not always safe. This is especially true when your condition might evaluate to a falsy non-boolean like 0. From my experience, using the ternary operator leads to fewer bugs and a more predictable UI.

✅ Use:

condition ? <Component /> : null

🚫 Avoid:

condition && <Component />

When writing JSX in React or React Native, I choose clarity over cleverness. The ternary operator keeps my components clean and my debugging sessions short!

The post React Conditional Rendering: Logical AND vs Ternary Operator appeared first on TechOpt.

]]>
https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator/feed 0
When to Use (and Not Use) Tailwind CSS in 2025 https://www.techopt.io/programming/when-to-use-and-not-use-tailwind-css-in-2025 https://www.techopt.io/programming/when-to-use-and-not-use-tailwind-css-in-2025#comments Sun, 23 Feb 2025 22:11:20 +0000 https://www.techopt.io/?p=819 Introduction Tailwind CSS has solidified its place in the modern web development ecosystem, offering a utility-first approach that streamlines styling for complex projects. While Tailwind is a powerful tool, it’s not a one-size-fits-all solution. In 2025, Tailwind is more popular than ever, but there are cases where it may not be the best choice. Let’s […]

The post When to Use (and Not Use) Tailwind CSS in 2025 appeared first on TechOpt.

]]>
Introduction

Tailwind CSS has solidified its place in the modern web development ecosystem, offering a utility-first approach that streamlines styling for complex projects. While Tailwind is a powerful tool, it’s not a one-size-fits-all solution. In 2025, Tailwind is more popular than ever, but there are cases where it may not be the best choice. Let’s break down when to use Tailwind, and when to consider alternatives.

When to Use Tailwind CSS

1. Complex, Multi-Page Websites

Tailwind shines in large-scale, multi-page applications where design consistency is critical. With reusable utility classes, developers can ensure a unified UI without wrestling with conflicting styles from separate CSS files. Platforms like SaaS applications, dashboards, and content-heavy websites benefit immensely from Tailwind’s scalable approach.

2. Rapid Prototyping

If speed is a priority, Tailwind helps teams iterate faster. Its utility classes allow developers to style components directly in markup, reducing the need for custom CSS. This makes it ideal for MVPs, startup projects, and proof-of-concept applications where time-to-market is crucial.

3. Projects Requiring Design System Enforcement

Tailwind is a great fit for teams that need strict adherence to a design system. The ability to define custom themes, typography, and color palettes in the tailwind.config.js file ensures that styles remain consistent across all pages and components.

Tailwind CSS version 4, which was just released, takes this a step further. This new version of Tailwind allows for most configuration to be done right inside of your main CSS file.

4. Component-Based Frameworks (React, Vue, Svelte, Next.js, etc.)

For teams using modern frameworks, Tailwind works seamlessly with component-driven development. It allows styling to live alongside the component logic, promoting maintainability and reducing CSS file bloat.

5. Web Apps with a Long Development Lifecycle

Maintaining large applications is easier with Tailwind since it reduces CSS complexity. Unlike traditional CSS or preprocessor-based approaches, Tailwind minimizes global styles, making it easier to refactor and extend applications over time.

When Not to Use Tailwind CSS

1. Small, Static Websites or Simple Landing Pages

For one-page websites or simple marketing pages, Tailwind may be overkill. A minimal custom CSS file or even plain HTML/CSS may suffice. Using Tailwind in such cases could add unnecessary overhead without significant benefits.

2. Highly Unique, Artistic Designs

While Tailwind is flexible, highly creative or experimental designs with intricate animations, custom typography, and complex layouts might be better served with traditional CSS, SCSS, or CSS-in-JS. Tailwind’s structured approach may feel limiting for designers who prefer complete freedom over styles.

3. Teams Without Tailwind Experience

Despite its advantages, Tailwind has a learning curve. Developers unfamiliar with its utility-first approach may struggle initially. If a team lacks experience or doesn’t have time to invest in learning Tailwind, sticking to traditional CSS methodologies may be more efficient.

4. Legacy Codebases with Predefined Styles

If you’re working on a legacy project that already has well-structured CSS or a component library, integrating Tailwind could introduce inconsistencies and unnecessary complexity. Migrating to Tailwind in such cases should be a carefully considered decision.

5. Strict SEO or Performance-Optimized Websites Where Every KB Counts

While Tailwind’s PurgeCSS ensures minimal CSS footprint, in some ultra-performance-critical cases, writing minimal, handcrafted CSS might still be preferable. Projects that need to prioritize reducing external dependencies might opt for vanilla CSS instead.

Conclusion: When to use Tailwind CSS in 2025

Tailwind CSS is a top choice for complex, multi-page applications, design-consistent systems, and component-driven frameworks in 2025. However, it’s not always the best tool for every scenario.

For small static sites, highly creative designs, or legacy projects, traditional CSS approaches may still hold an advantage. Understanding when to use Tailwind, and when not to, will help you maximize efficiency while maintaining flexibility in your web development workflow.

The post When to Use (and Not Use) Tailwind CSS in 2025 appeared first on TechOpt.

]]>
https://www.techopt.io/programming/when-to-use-and-not-use-tailwind-css-in-2025/feed 2
Five Important Technical SEO Tips for 2025 https://www.techopt.io/programming/five-important-technical-seo-tips-for-2025 https://www.techopt.io/programming/five-important-technical-seo-tips-for-2025#respond Thu, 02 Jan 2025 14:37:00 +0000 https://www.techopt.io/?p=641 As we step into 2025, staying ahead in the digital landscape requires adopting cutting-edge practices. To help you optimize your website, here are five important technical SEO tips for 2025 that will enhance your site’s performance and search visibility. From improving loading speeds to balancing lazy loading and server-side rendering, these tips will ensure your […]

The post Five Important Technical SEO Tips for 2025 appeared first on TechOpt.

]]>
As we step into 2025, staying ahead in the digital landscape requires adopting cutting-edge practices. To help you optimize your website, here are five important technical SEO tips for 2025 that will enhance your site’s performance and search visibility. From improving loading speeds to balancing lazy loading and server-side rendering, these tips will ensure your website meets modern SEO standards.

As a web developer, part of our job is to make sure we’re using available optimizations and adhering to the latest best coding practices. Many of these optimizations rely heavily on clever use of HTML and JavaScript, so technical expertise is key.

1. Optimize LCP Loading Speed

Largest Contentful Paint (LCP) is a critical metric in Google’s Core Web Vitals. It measures the time it takes for the largest visible content element—usually an image or block of text—to load and become visible to users. A slow LCP can negatively impact user experience and search rankings.

To improve LCP:

  • Avoid lazy loading the largest image or hero image on your page. This ensures the browser can prioritize its rendering immediately.
  • Use efficient image formats like WebP or AVIF for better compression.
  • Preload critical resources, such as fonts and above-the-fold images, to help the browser fetch them early.

These changes often involve direct modifications to your HTML structure and strategic resource management through JavaScript to ensure optimized delivery.

2. Lazy Load Other Images

While the largest image should not be lazy-loaded, smaller images and those below the fold can and should be. Lazy loading these assets reduces the initial page size and improves loading speed, leading to a better user experience and higher SEO performance.

Use the loading="lazy" attribute for images or leverage JavaScript libraries for more control. For example:

<img src="example.jpg" loading="lazy" alt="Descriptive Alt Text">

Strategic use of HTML attributes and JavaScript allows you to control how and when resources load, ensuring optimal performance.

3. Lazy Load Unnecessary JavaScript and Unnecessary Content Below the Fold

Lazy loading isn’t just for images—you can also apply it to JavaScript and other content below the fold. This minimizes the amount of resources the browser processes initially, reducing the time to interactive (TTI).

Here’s an example using React:

import React, { lazy, Suspense } from 'react';

const LoginModal = lazy(() => import('./LoginModal'));

function App() {
  const [showModal, setShowModal] = React.useState(false);

  return (
    <div>
      <button onClick={() => setShowModal(true)}>Open Login</button>
      {showModal && (
        <Suspense fallback={<div>Loading...</div>}>
          <LoginModal />
        </Suspense>
      )}
    </div>
  );
}

This approach defers loading the login modal until the user clicks the button. Frameworks like Vue, Angular, or vanilla JavaScript also support similar lazy loading techniques using import(), which you can read more about here.

Implementing these optimizations requires careful use of JavaScript to balance resource management and functionality.

4. Don’t Lazy Load Content Vital to Search Engines

While lazy loading has its benefits, overusing it can backfire. Content critical for SEO, like metadata, structured data, and primary text visible to users, should not be lazy-loaded. Search engines may not fully index this content, harming your rankings.

To ensure vital information is always available:

  • Use Server-Side Rendering (SSR) for pages you need to rank well in search engines. SSR renders content on the server before sending it to the browser, ensuring it’s accessible to search engines and users.
  • Prioritize preloading critical content while deferring less essential resources.

This balance often involves designing your HTML to ensure critical content is included upfront and leveraging JavaScript for secondary features. Therefore, avoid over-optimization that can harm your site’s accessibility and SEO.

5. Minimize Time to Interactive

Time to Interactive (TTI) measures how quickly a page becomes fully interactive. High TTI can frustrate users and impact rankings.

To optimize TTI:

  • Use SSR to render the initial view faster.
  • Choose smaller, lightweight JavaScript libraries and avoid running unnecessary scripts on load.
  • Combine lazy loading with efficient bundling to defer non-critical scripts until needed.

Reducing TTI requires fine-tuning your JavaScript execution and crafting your HTML to load essential resources efficiently. By optimizing these elements, you can enhance user satisfaction and meet Google’s performance benchmarks.

Conclusion

By following these five technical SEO tips for 2025, you can improve your site’s speed, usability, and search engine visibility. Many of these strategies rely on making deliberate adjustments to your HTML and JavaScript to strike the perfect balance between performance and accessibility. Stay proactive, and your website will thrive in the ever-changing SEO landscape.

The post Five Important Technical SEO Tips for 2025 appeared first on TechOpt.

]]>
https://www.techopt.io/programming/five-important-technical-seo-tips-for-2025/feed 0
Add Tailwind CSS to an Existing Next.js Project https://www.techopt.io/programming/add-tailwind-css-to-an-existing-next-js-project https://www.techopt.io/programming/add-tailwind-css-to-an-existing-next-js-project#respond Sat, 03 Aug 2024 20:00:26 +0000 http://localhost:8080/?p=88 If you have an existing Next.js project using plain CSS or CSS modules, you may decide to add Tailwind CSS at some point. During recent years, Tailwind CSS has become increasingly popular for its simplicity and ease-of-use. The good news is Tailwind can inter-op with plain CSS and CSS modules quite easily without affecting your […]

The post Add Tailwind CSS to an Existing Next.js Project appeared first on TechOpt.

]]>
If you have an existing Next.js project using plain CSS or CSS modules, you may decide to add Tailwind CSS at some point. During recent years, Tailwind CSS has become increasingly popular for its simplicity and ease-of-use.

The good news is Tailwind can inter-op with plain CSS and CSS modules quite easily without affecting your existing work. At the same time, this makes it easy to adopt gradually, even in big projects with lots of custom styling already.

Adding Tailwind CSS to the Project

To add Tailwind to an existing Next.js project, you can follow these steps.

1. Install Tailwind Package

Install the tailwindcss package with yarn or npm by running

yarn add tailwindcss

2. Add (or Update) postcss.config.js

If you don’t already have a postcss.config.js file in your project’s root, create one with the following contents:

// postcss.config.js

module.exports = {
  "plugins": [
    ["tailwindcss", {}]
  ]
}

If you do already have a postcss.config.js file, just add the tailwindcss plugin to the list of plugins like above.

3. Create Tailwind Config File

Create a tailwind.config.js or tailwind.config.ts file in your project’s root with the following contents:

// tailwind.config.ts
// This example is using TypeScript instead of plain JavaScript

import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
 
    // Or if using `src` directory:
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

export default config;

Or if you prefer plain JavaScript:

// tailwind.config.js
// This is for JavaScript

module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
 
    // Or if using `src` directory:
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

4. Add Tailwind Directives to globals.css File

Your Next.js project should already have a globals.css file or equivalent. Add the Tailwind directives at the top of it:

/* globals.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

/* rest of css code */

5. Test it Out!

Start your dev server with yarn run dev and test out some Tailwind in your React code. You can do something like the following:

// index.tsx

export default function Home() {
  return (
    <div className="text-green-400 font-bold underline">
      Hello world!
    </div>
  )
}

You should see some green text, underlined in bold!

Inter-oping Tailwind CSS with Existing CSS & CSS Modules

If you’re already using regular CSS or CSS modules in your project, thankfully you can use Tailwind CSS class names with existing class names.

CSS modules just output a class name, so we can use our CSS module classes in addition to the Tailwind classes.

Using Tailwind Classes with CSS Modules

CSS modules just outputs unique class names. Because of this, we can use existing CSS module classes with Tailwind CSS by using template literals:

// index.tsx
import styles from '@/styles/pages/Home.module.css'

export default function Home() {
  return (
    <div className={`${styles.styled_text} text-green-400 font-bold underline`}>
      Hello world!
    </div>
  )
}

This will combine our rules from our existing CSS modules with the Tailwind classes we’ve added.

Optional: Disabling Opinionated Default Tailwind Styling Decisions

When you install Tailwind, it makes some opinionated default styling decisions on some elements to normalize the look across browsers. This is fine for new projects, but if you’ve been using CSS modules up until this point, it may mess up some of your existing styling.

To disable this behaviour, you can add the option preflight: false under the corePlugins option in your Tailwind config file, like so:

// tailwind.config.ts
// This example is using TypeScript instead of plain JavaScript

import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
  corePlugins: {
    preflight: false
  }
}

export default config;

This will disable the default normalization styling decisions Tailwind makes, such as making all headers normal-sized text and not bold.

Remarks

  • This guide was adapted from the official Tailwind guide to go more in depth, and assumes the use of newer standards such as TypeScript.
  • Some guides mention installing postcss and autoprefixer packages in addition to Tailwind, but this isn’t necessary since Next.js comes with PostCSS support built-in.

The post Add Tailwind CSS to an Existing Next.js Project appeared first on TechOpt.

]]>
https://www.techopt.io/programming/add-tailwind-css-to-an-existing-next-js-project/feed 0