Brief Overview of WebDev Using Next.JS and React

What is Next.js?

Next.js is a React framework for building full-stack web applications.

What is React?

React lets you build user interfaces out of individual pieces called components. Create your own React components like Thumbnail, LikeButton, and Video. Then combine them into entire screens, pages, and apps.

Some Next.js Benefits

  • Automatic image, font, and script optimizations for improved UX and Core Web Vitals (Learn more)
  • Client and server rendering
  • Content pre-fetching with the <Link> component when the link is hovered or enters the viewport
  • Client-side navigation (JavaScript-based page transitions) using the <Link> component, which is faster than default browser-based navigation using the <a> tag
  • Optimized CSS
  • Layouts (shared UI) don’t rerender on navigation from one page to another
  • Automatic configuration of low-level tools like bundlers and compilers
  • and much more

App Router and Pages Router

Next.js supports two different routers: App router and Pages router. The App router is newer and supports new React features.

Pre-requisite knowledge

In order to successfully use Next.js, you should know

Knowledge of the following is optional but recommended

Installation

  • Install Node.js 18.18 or later.
  • Run npx create-next-app@latest

After the prompts, create-next-app will create a folder with your project name and install the required dependencies.

You will get a folder structure like this

The “app” folder is where you source code is.

If you were using a the Pages router, your source code would be in a “pages” folder instead.

During installation, if you chose to have your code in a “src” folder, then the “app” or “pages” folders would be nested in a “src” folder.

The “public” folder is where you store static assets like images, fonts, etc.

In package.json, you will have some scripts like

  • next dev starts the development server
  • next build builts the application for production
  • next start starts the production server
  • eslint runs ESLint (for linting)

create-next-app created a starter home page (page.js) and layout (layout.js).

Run npm run dev to start the dev server.

Open http://localhost:3000/ in a browser to see the starter page.

Project Structure

View a listing of the various types of files in an Next.js app.

File-system-based Routing

Each folder represents a route segment that is mapped to a corresponding segment in a URL path. But, a route is not publicly accessible until a page.js or route.js file is added to a route segment.

Creating a Page

page is UI that is rendered on a specific route. 

export default function Page() {
  return <h1>Hello Next.js!</h1>
}

Creating a Layout

A layout is UI that is shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not rerender.

export default function DashboardLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {/* Layout UI */}
        {/* Place children where you want to render a page or nested layout */}
        <main>{children}</main>
      </body>
    </html>
  )
}

The above is a root layout. It is required and must contain html and body tags.

You can also create nested layouts. Parent layouts wrap children layouts.

Dynamic segments

Dynamic segments allow you to create routes that are generated from data. For example, instead of manually creating a route for each individual blog post, you can create a dynamic segment to generate the routes based on blog post data. In the example below, [slug] is a dynamic segment.

app/blog/[slug]/page.js

export default async function BlogPostPage({ params }) {
  const { slug } = await params
  const post = await getPost(slug)
 
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  )
}

Server vs Client Components

Server components are components that are dynamically rendered on the server.

Client components are components that are statically rendered on the client (browser).

Rendering with search params

In a Server Component page, you can access search parameters using the searchParams prop:

app/page.jsx

export default async function Page({ searchParams }) {
  const filters = (await searchParams).filters
}

Dynamic rendering

Using searchParams opts your page into dynamic rendering because it requires an incoming request to read the search parameters from. Use the searchParams prop when you need search parameters to load data for the page (e.g. pagination, filtering from a database).

Static rendering

Client Components can read search params using the useSearchParams hook. Use useSearchParams when search parameters are used only on the client (e.g. filtering a list already loaded via props).

Linking between pages

You can use the <Link> component to navigate between routes. <Link> is a built-in Next.js component that extends the HTML <a> tag to provide prefetching and client-side navigation. Next.js automatically prefetches routes linked with the <Link> component when they enter the user’s viewport.

import Link from 'next/link'
 
export default function Layout() {
  return (
    <html>
      <body>
        <nav>
          {/* Prefetched when the link is hovered or enters the viewport */}
          <Link href="/blog">Blog</Link>
          {/* No prefetching */}
          <a href="/contact">Contact</a>
        </nav>
        {children}
      </body>
    </html>
  )
}

Linking and Navigation

Server Rendering

There are two types of server rendering, based on when it happens:

  • Static Rendering (or Prerendering) happens at build time or during revalidation and the result is cached.
  • Dynamic Rendering happens at request time in response to a client request.

Prefetching

Prefetching is the process of loading a route in the background before the user navigates to it. How much of the route is prefetched depends on whether it’s static or dynamic:

  • Static Route: the full route is prefetched.
  • Dynamic Route: prefetching is skipped, or the route is partially prefetched if loading.tsx is present.

Prefetching happens when the link enters the viewport. If this consumes too much resources, you can just prefetch only on hover.

app/ui/hover-prefetch-link.js

'use client'
 
import Link from 'next/link'
import { useState } from 'react'
 
function HoverPrefetchLink({ href, children }) {
  const [active, setActive] = useState(false)
 
  return (
    <Link
      href={href}
      prefetch={active ? null : false}
      onMouseEnter={() => setActive(true)}
    >
      {children}
    </Link>
  )
}

Streaming

Client-side transitions

Traditionally, navigation to a server-rendered page triggers a full page load. Next.js avoids this with client-side transitions using the <Link> component. Instead of reloading the page, it updates the content dynamically by:

  • Replacing the current page with the prefetched loading state or a new page if available.
  • Keeping any shared layouts and UI.

Server and Client Components

Layouts and Pages are Server Components by default.

<Link> is a Client Component.

Use Client Components when you need:

Use Server Components when you need:

  • Fetch data from databases or APIs close to the source.
  • Use API keys, tokens, and other secrets without exposing them to the client.
  • Reduce the amount of JavaScript sent to the browser.
  • Improve the First Contentful Paint (FCP), and stream content progressively to the client.

For example, the <Page> component is a Server Component that fetches data about a post, and passes it as props to the <LikeButton> which handles client-side interactivity.

Note that the <LikeButton> component has ‘use client’ at the top.

What is hydration?

Hydration is React’s process for attaching event handlers to the DOM, to make the static HTML interactive.

Pre-rendering vs no pre-rendering

With pre-rendering (using Next.js), HTML is rendered on the server (server-side static rendering) and sent to the client (browser), similar to how PHP works. Then JS loads in the browser to “hydrate” the DOM to make it interactive, including links that were created using the <Link> component rather than the <a> tag. If you disable JavaScript in the brower and load a page, the page will load, but it will not be interactive.

If you create a plain React.js app, then all page content is generated dynamically in the browser by JavaScript as a single-page application (SPA). That is why if you disable JavaScript in the brower and load a page, the page will load, but you won’t see anything.

Next.js has 2 kinds of pre-rendering:

  1. Static Generation is the pre-rendering method that generates the HTML at build time. The pre-rendered HTML is then reused on each request. This is like using Next.js as a static site generator.
  2. Server-side Rendering is the pre-rendering method that generates the HTML on each request. This is like how PHP sites, like WordPress, work.

Fetching Data

You can fetch data in Server and Client Components.

Fetching data in server components

You can fetch data in Server Components using:

  1. The fetch API
  2. An ORM or database

With the fetch API

To fetch data with the fetch API, turn your component into an asynchronous function, and await the fetch call. For example:

With an ORM or database

Since Server Components are rendered on the server, you can safely make database queries using an ORM or database client. Turn your component into an asynchronous function, and await the call:

Fetching data in client components

There are two ways to fetch data in Client Components, using:

  1. React’s use hook
  2. A community library like SWR or React Query

Learn more

Updating Data

You can update data in Next.js using React’s Server Functions. A Server Function is an asynchronous function that runs on the server. They can be called from client through a network request, which is why they must be asynchronous.

Define a Server Function by using the “use server” directive at the top of an asynchronous function.

Server Functions can be inlined in Server Components by adding the "use server" directive to the top of the function body:

There are two main ways you can invoke a Server Function:

  1. Forms in Server and Client Components
  2. Event Handlers and useEffect in Client Components

Forms

React extends the HTML <form> element to allow Server Function to be invoked with the HTML action prop.

Event Handlers

You can invoke a Server Function in a Client Component by using event handlers such as onClick.

Show a pending state with a loading indicator

Revalidating

After performing an update, you can revalidate the Next.js cache and show the updated data by calling revalidatePath or revalidateTag within the Server Function:

Redirecting

You may want to redirect the user to a different page after performing an update. You can do this by calling redirect within the Server Function.

Cookies

You can getset, and delete cookies inside a Server Action using the cookies API:

CSS

Tailwind CSS

CSS Modules

CSS Modules locally scope CSS by generating unique class names. This allows you to use the same class in different files without worrying about naming collisions. Learn more

Global CSS

You can use global CSS to apply styles across your application.

Next.js recommends using

  • global styles for truly global CSS (like Tailwind’s base styles),
  • Tailwind CSS for component styling, and
  • CSS Modules for custom scoped CSS when needed.

External Stylesheets

In React 19, <link rel="stylesheet" href="..." /> can also be used. 

Image Optimization

The Next.js <Image> component extends the HTML <img> element to provide:

  • Size optimization: Automatically serving correctly sized images for each device, using modern image formats like WebP.
  • Visual stability: Preventing layout shift automatically when images are loading.
  • Faster page loads: Only loading images when they enter the viewport using native browser lazy loading, with optional blur-up placeholders.
  • Asset flexibility: Resizing images on-demand, even images stored on remote servers.

The src property can be a local or remote image.

Better to store images locally, if possible. Next.js will automatically determine the intrinsic width and height. These values are used to determine the image ratio and prevent Cumulative Layout Shift while your image is loading.

Font Optimization

Metadata

Static metadata

To define static metadata, export a Metadata object from a static layout.js or page.js file. 

Package Managers

Next.js recommends using pnpm as it’s faster and more efficient than npm or yarn.

npm install -g pnpm

Then, to install packages, run pnpm i

To start the dev server, run pnpm dev

Common Folder Structure

  • /app: Contains all the routes, components, and logic for your application, this is where you’ll be mostly working from.
  • /app/lib: Contains functions used in your application, such as reusable utility functions and data fetching functions.
  • /app/ui: Contains all the UI components for your application, such as cards, tables, and forms.
  • /public: Contains all the static assets for your application, such as images.

Demo

This GitHub repo contains pages that demonstrate some of the concepts above. Browse the repo to see the code structure. The demo site is hosted on Vercel, the makers of Next.js.

Live PageCode
Demo home pageView code
Demo <Link> componentView code
Demo using clsxView code
Demo external component – Ant DesignView code
Demo external component – MantineView code
Demo external component – Material UIView code
Demo external component – ShadcnView code
Demo external component – Tailwind PlusView code
Demo using custom fontsView code
Demo using <Image> componentView code
Demo adding page metadataView code
Demo using a nested layoutView code
Demo using external JavaScriptView code

Video Editing with Capcut

In this post, I’ll share my process for how to make a traditional video in Capcut. Specifically, I’ll show how to make a video that:

  • comprises a collection of video and image clips
  • has a simple crossfade (mix, fade-in/fade-out) transition between clips
  • has background music with a crossfade between music clips
  • improves audio quality
  • uses AI to stabilize some shaky video footage
  • improves the color and lighting of some clips
  • animates some images with a subtle zoom effect
  • animates some images to create rolling credits
  • freezes a frame in a video clip
  • has text overlays

Download and install Capcut

Visit the Capcut website, download Capcut and install it.

Import video and image footage

  1. Open Capcut
  2. Create a new project
  3. Click the default project name at the top center and rename it to something descriptive, e.g. My Vacation
  4. Click the “Media” tab at the top left and then click “Import” tab below it.
  5. Click the “Import” button or drag your footage (audio, video, images) to the assets pane.

Use the filter dropdown to filter assets by type (video, audio, image, etc).

Use the sort dropdown to sort assets, e.g. by date created, etc. I find that sorting by “Time created” and “Earliest to latest” puts my assets in the order I want them in so I can just select all assets and drag them to the timeline.

Drag some or all of your footage to the timeline at the bottom

Drag the zoom slider at the top right of the timeline pane to zoom the timeline in and out.

Trim images

When you drag images to the timeline, the duration will be whatever the setting is under Options, which defaults to 5 seconds. If you want to change the default to, say, 3 seconds, go to Menu > Settings > Edit (tab) > Image Duration and change the value to 3.

Click on an image in the timeline. In the right pane, you will see various options to edit the image.

The playhead is a visual marker that indicates the current position or frame being viewed in the preview pane. Drag the playhead to anywhere above the image in the timeline. You will see a preview of the image in the center in the preview pane.

Click the play button in the preview pane to preview how the image will appear relative to the rest of the video project.

If the image duration is too short or too long, you can extend the duration by dragging the left or right edge of the clip in the timeline to the left or right. You can also position the playhead at a particular time and click one of the following buttons:

  1. SPLIT: to split the image clip into two clips
  2. DELETE LEFT: to delete the portion of the image to the left of the playhead
  3. DELETE RIGHT: to delete the portion of the image to the right of the playhead

To see the duration of an image, zoom out on the timeline and look at the duration label on the clip in the timeline. For example, the image clip below is 3 seconds long.

The video clip below is 23 seconds and 8 frames long.

Trim Videos

Trimming video clips on the timeline is similar to trimming images. Click on a video clip in the timeline. You will see a preview of the video in the preview pane. In the right pane, you will see various options to edit the video clip.

In the right pane, click “Speed” to see the video clip’s duration. If you change the duration value here, the video clip’s speed will change accordingly. If you don’t want to speed up or slow down the video, you’ll need to trim the video clip the same way you trim image clips:

  • drag the left end of the video clip in the timeline to the right
  • drag the right end of the video clip in the timeline to the left
  • split, delete left, or delete right the video clip relative to where the playhead is in the timeline

Speed up or slow down video clips

If your video clip is too slow or too fast, you can speed it up or slow it down. As in the previous step, click the video clip in the timeline and then click the “Speed” tab in the right pane.

Speed up

To speed up the video clip, e.g, 2x for twice the speed, just drag the speed marker to the right. The duration of the clip will change accordingly.

Slow down

To slow down the video clip, e.g. 0.5x for half the speed, drag the speed marker to the left. The duration of the clip will change accordingly. Note that if your video clip was shot at 30 frames per second (fps) and you slow down the clip by 50% (0.5x), the resulting video will stutter due to an insufficient number of frames. This is why you should shoot video at a high frame rate, e.g. 60 or 120 fps, if you know you want to play it back in slow motion, which is usually done for action scenes.

If you didn’t shoot at a high fps, you can use Capcut to smoothen the slow-mo effect by either

  • frame blending
  • optical flow

The results are not as good as a high-fps video, but they’re better than without smoothening, especially using the “optical flow” option.

Add transitions between clips

There are many transition effects available. I prefer to use the simple crossfade (mix) transition, which gradually fades out one clip and fades in the next clip. To add this transition between two adjacent clips, click the “Transitions” tab in the left pane, type “mix” in the search field, and drag the mix transition icon down to the timeline between two clips. If necessary, zoom the timeline out. You’ll see a semi-white section between the two clips representing the transition. If you move the playhead to that transition area in the timeline, you can see a preview of the transition in the preview pane, showing a blending of the two clips.

If you want to apply the same transition to all clips, click one transition in the timeline and then, in the right pane, click the “Apply to all” button.

Add background music

  1. Click the “Audio” tab in the left pane.
  2. Click the “Import” button to import songs (MP3) from your computer.
  3. Drag a song from the list of songs down to the timeline below the main video track.

As with still images and video clips, you can trim audio clips in the same manner.

If you want to crossfade two adjacent songs,

  1. put the 2nd song on a separate track below the first song’s track
  2. zoom in on the timeline and scroll to where the two songs meet
  3. click the 1st song and, in the right pane, set a fade out duration of, say, 1 second
  4. click the 2nd song and, in the right pane, set a fade in duration of, say, 1 second
  5. position the playhead just before the end of the first song
  6. preview the audio crossfade in the preview pane

Notice the black curve in the audio tracks showing the fade effect.

When you add audio or music track, if your video clips contain audio, you’ll hear audio from all tracks containing audio. If you want to mute all audio from all clips in the main track, click the audio icon as shown below.

If you want to adjust the volume or mute just a single video clip, click on the clip in the timeline, then in the right pane, click the “Audio” tab and drag the volume slider.

Improve audio quality

The audio in your video clips may contain background noise as well as vocals. To improve the audio quality, select the relevant clips and choose from the following options in the “Audio” panel.

  • To reduce background noise, e.g. humming or the sound of an engine, check the “Reduce noise” checkbox
  • To improve vocals, check the “Enhance voice” and/or “Isolate voice” checkboxes. Note that the “Isolate voice” options strips out all audio, leaving only vocals.”
  • To normalize the loudness of all background music clips, select all clips and check the “Normalize loudness” checkbox.
  • Slide the volume slider to increase or decrease the volume as needed.

Adjust color and lighting

You can adjust the color and lighting for both image and video clips individually.

  1. Click on a clip in the timeline
  2. Move the playhead to that clip
  3. In the right pane, click “Adjust” > “Basic” > “Auto adjust”
  4. Slide the “Auto adjust” intensity slider until you like how the clip looks in the preview pane.

You can also manually adjust the color by tweaking various color settings in the right pane.

I find adjusting color is especially helpful for brightening a dark image or video. Here’s how one clip looks before and after applying “auto adjust”.

Before
After

Stabilize a shaky video

If your video footage was taken with a camera that doesn’t include mechanical stabilization (like a gimbal) or software stabilization, then the resulting footage could be annoyingly shaky. Capcut can try to stabilize your footage at the expense of cropping a portion of the video. To stabilize a shaky video,

  1. click on a video clip in the timeline
  2. in the right pane, click the “Video” tab and check the “Stabilize” option.

Animate images

For certain photos, I like to apply a subtle zoom-out animation effect to them. To do this,

  1. click on the image clip in the timeline
  2. move the playhead in the timeline to where the image clip is
  3. click the up arrow key to move the playhead to the beginning of the clip
  4. in the right pane, click “Video” > “Basics”, change the “scale” value to 200% and click the diamond icon to set a keyframe
  5. click the down arrow key to move the playhead to the end of the clip
  6. in the right pane, click “Video” > “Basics” and change the “scale” value to 100%
  7. drag the playhead from the beginning to the end of the clip. You should see the image zoom out. You can also click the play button in the preview pane to preview the animation.
Playhead is at the beginning of the clip
Scale at 100%
Scale at 100%
Scale at 200%
Scale at 200% with keyframe set
Playhead at end of clip

Create rolling credits

There are different ways to create rolling credits. The way I’m about to show you involves slowly animating an image’s position upwards. Therefore, you’ll need to create a tall image with the content you want in it, like this

  1. Add this image to the timeline
  2. Select the image in the timeline
  3. Position the playhead in the timeline where the image is
  4. Click the up arrow key to move the playhead to the beginning of the clip
  5. In the right pane, click “Video” > “Basics”
  6. Change the “scale” value until you like how the credits image looks in the preview. In the screenshot below, I set it to 500%.
  7. Change “position” Y value to a value that moves the top of the image near the bottom of the preview pane. In the screenshot below, I set it to -3300.
  8. Click the diamond icon to set a keyframe
  9. Click the down arrow key to move the playhead to the end of the clip
  10. in the right pane, click “Video” > “Basics” and change the “position” Y so that the bottom of the image is near the top of the preview pane. In the screenshot below, I set the value to 3300.
  11. Drag the playhead from the beginning to the end of the clip. You should see the image roll up. You can also click the play button in the preview pane to preview the animation.

Freeze a frame in a video clip

Sometimes, you may want to freeze a frame in a video clip for a few seconds. For example, in the screenshot below, there’s a video clip of a vehicle moving along a road and a sign showing various destinations. To freeze the frame at the point when the sign is shown,

  1. move the playhead to the timestamp where you want to freeze a frame
  2. click on the video clip in the timeline
  3. click the “freeze” button above the timeline

The video clip will be split at that point and you will see a still image of the frame added to it. You can then adjust the duration of the image. Make sure not to add any transitions between the video clip and the still image. You can group the two clips or create a component to prevent accidentally adding a transition between them.

After freezing the frame, the video clip is split and a still image of the frame is appended

Add a text overlay

There will be times when you’ll want to overlay text on a scene to describe a location or what’s happening as in the following screenshot.

To do this,

  1. click the “Text” tab in the left pane
  2. drag the “Default text” item to the timeline on a track above the clip where you want the text to appear
  3. drag the ends of the text clip in the timeline to increase or decrease the duration
  4. click on the text clip in the timeline and, in the right pane, edit the text and various other properties, e.g. background color and background opacity
  5. in the preview pane, drag the text overlay to where you want it. you can also drag the corners to resize it.

Add a marker on the timeline or a clip

When editing a video, it can be helpful to add markers at certain points to remind you where a specific moment is. For example, you may want to align some a music clip to a specific moment. To do this,

  1. move the playhead to the timestamp where you want to add a marker
  2. click the marker button above the timeline

You will see a light blue marker added on the timeline.

Export your video

Click the light blue “Export” button at the top right to export the video.

Export a still image of a video clip

  1. move the playhead to the timestamp where you want to freeze a frame.
  2. click the hamburger menu (3 horizontal lines) at the top-right corner of the preview pane
  3. click “Export still frames”
  4. if you don’t want the still image added to your project, uncheck the “Import project” checkbox

Create a fast-rewind effect followed by a slow-motion effect

For fast-moving scenes, you may want to replace the scene in slow motion. One way to do this is to show the original clip (1) followed by a fast rewind of the clip (2) followed by a slow-motion version of the clip (3) as shown in the screenshot below.

To do this,

  1. copy and paste the original clip twice and place the copies after the original clip on the timeline
  2. click the 2nd clip to select it and then click the “Reverse” button above the timeline
  1. Change the speed of the 2nd clip to something like 5x.
  1. click the 3rd clip to select it and then change the speed to something like 0.2x.

Easily Remove Grout Haze From Tile

When applying grout to tile, you’re supposed to wait 15-30 minutes before wiping the grout of the tile while leaving the grout between each tile. This is easier said that done. No matter how good you are, you’ll probably be left with a thin layer of grout on your tile. If you use a light-colored grout on light-colored tile, you won’t notice the haze except at certain angles in certain lighting. The haze can resemble hard water stains. If you use a dark-colored grout on light tile or a light-colored grout on dark tile, the haze is more prominent, and your tile can look dirty. See example below.

Before

You can try to scrub with soap or even a steam cleaner, but that will have zero effect. Luckily, there is an amazing chemical product that can relatively easily remove the grout haze from tile. With Aqua Mix 1 Qt. Cement Grout Haze Remover by Custom Building Products, you just mix the liquid with water, pour some one the tile, wait a while, then rub the haze off. For tougher haze, don’t mix with water. In my case, I poured the liquid at full strength without adding water into a spray bottle, sprayed the liquid on the tile, then wiped the haze off with a rag. As most comments say on the Home Depot product page, this stuff is “amazing”!

After
Aqua Mix 1 Qt. Cement Grout Haze Remover by Custom Building Products

Quickly and Easily Remove Weeds From Your Driveway

To easily remove weeds from control joints in your concrete driveway, use an angle grinder with a wire wheel. I use a 4.5″ Ryobi brushed, cordless angle grinder. Don’t use a brushless angle grinder because it can’t be used for this purpose. I prefer using a knotted wire wheel. A non-knotted wire wheel works as well, but I find it better for cleaning control joints after removing large weeds using the knotted one.

Knotted Wire Wheel

Non-knotted Wire Wheel

To prevent kickback, stand and drag the tool to the right as shown in the photo below.

If the angle grinder flange lock nut is stuck, use either a pipe wrench or a thin wrench to unlock it. For convenience, clamp the angle grinder to a stationary vise.

English Muffin Breakfast Recipe

A few years ago, I flew to Korea on Hawaiian Airlines and was served a warm English muffin containing a turkey patty and egg. As cheap and simple as it looked, I wasn’t expecting much, but it turned out to be so good, I had to try to recreate it. I think I figured it out. Here’s my recipe.

Ingredients

Instructions

  1. Spray some cooking oil on a frying pan.
  2. Fry the egg in the shape of the muffin. I like to use this egg pancake frying pan that I got on Amazon. Optionally, pierce the yolk.
  3. Sprinkle some salt and pepper on the egg and cover the pan so the top of the egg gets cooked.
  4. Slice the muffin into 2 halves.
  5. Heat the muffin in a microwave for 1 minute to warm and soften it up. This is especially necessary if the muffins were refrigerated, cold, and hard.
  6. Since the turkey patties are small, defrost 2 of them in a microwave for 2 minutes and 30 seconds.
  7. Spread some hummus on all inner sides of each muffin half.
  8. Cut one of the turkey patties in half so that one and a half muffins can cover most of the muffin.
  9. Put 1.5 turkey patties next to each other, cover it with half a cheese slice, and microwave for 25 seconds.
  10. Assemble the muffin as shown in the photos below.

Saudi Arabia Trip 2025

Weather by Month

Sunrise & Sunset

SunriseSunset
May 11, 20255:46 AM6:53 PM
May 19, 20255:43 AM6:56 PM

Itinerary at a Glance

Saturday, May 10 – Fly to KSA

Start TimeEnd TimeActivity
4:21 PM5:49 PMFly from SF (SFO) to Los Angeles (LAX)
5:49 PM9:00 PM3-hour layover at LAX
9:00 PMFly from LAX to Jeddah, KSA

Sunday, May 11 – Fly to KSA

Start TimeEnd TimeActivity
10:20 PMLand in Jeddah, KSA
11:00 PM11:30 PMDriver takes us from airport to Luli’s house

Monday, May 12 – Medinah

Start TimeEnd TimeActivity
7:00 AM8:00 AMBreakfast at … (Shakshouka, Roz Bi-Laban)
8:30 AM9:00 AMUber from Luli’s house to Jeddah airport train station
10:00 AM11:45 AMBullet train from Jeddah airport to Medina ($62)
12:00 PM12:30 PMUber from train station to the Prophet’s mosque
12:30 PM1:00 PMLunch at Al Baik (in front of mosque)
1:00 PM4:30 PMVisit the Prophet’s mosque
4:30 PM5:30 PMDinner at …
5:30 PM6:00 PMUber to train station
7:00 PM8:48 PMBullet train from Medina to Jeddah ($62)
9:00 PM9:30 PMUber to Nawal’s house

Tuesday, May 13 – Mecca

Start TimeEnd TimeActivity
Breakfast at … (Shakshouka, Roz Bi-Laban)
9:00 AMHired driver (Ali) picks us up at Nawal’s house. Bring all bags.
9:00 AM10:00 AMDrive from Nawal’s house in Jeddah to Farida’s house in Mecca
10:00 AM10:30 AMRest / chat with Farida
10:30 AM11:00 AMLeave small bags at Farida’s house. Drive to Miqat of Tan’im (Masjid-e-Aisha) 7.5 KM away from Masjidil Haram.
11:00 AM11:30 AMPray sunnah with intention to do umrah
11:30 AM12:00 PMDrive to Masjid Al-Haram
12:00 PM3:00 PMDo umrah (tawaf and sa’i). Driver drives back to Jeddah and drops off our luggage at Riyadh’s house.
3:00 PM4:00 PMLunch at Al Shorfa (next to mosque)
4:00 PM 4:10 PMUber to Farida’s house
8:00 PM9:00 PMBullet train from Mecca to Jeddah airport ($34)
9:00 PM9:30 PMUber to Riyadh’s house
10 PM11 PMBuy Baklava at Baklavaci بكلافجي

Wednesday, May 14 – Jeddah

Start TimeEnd TimeActivity
8:00 AM9:00 AMBreakfast at Maison De Zaid دار زيد
12:00 PM1:00 PMLunch at Ulfat Mutabbaq
3:00 PM4:00 PMDrive to Arabian Treks Campground
4:00 PM9:00 PMDesert Safari (includes dinner)
9:00 PM10:00 PMDrive back to Jeddah

Thursday, May 15 – Jeddah

Start TimeEnd TimeActivity
8:00 AM9:00 AMBreakfast at … (Shakshouka, Roz Bi-Laban)
12:00 PM1:00 PMGo to Marina
1:00 PM7:00 PMPrivate boat ride to Bayada Island in the Red Sea
9:00 PM10:00 PMDinner at Al Nakheel Lebanese restaurant

Friday, May 16 – Jeddah

Start TimeEnd TimeActivity
6:00 AM9:00 AM
2:00 PM3:00 PMLunch at Saraya Latif Turkish restaurant
5:30 PM6:00 PMUber to Al-Balad
6:00 PM6:30 PMCoffee at Roshan Cafe
6:30 PM8:30 PMJeddah Old Town Walking Tour (Al-Balad)

The place comes alive at night, so best to go right before sunset, which is at 7 PM.
8:30 PM9:00 PMDinner at Al-Basali Seafood Restaurant in Al-Balad
9:00 PM10:00 PMWalk the Jeddah corniche at night / Jeddah Yacht Club

Saturday, May 17 – Jeddah

Start TimeEnd TimeActivity
9:00 AM10:00 AMBreakfast at Twenty Four Restaurant
12:00 PM1:00 PMBuy Baklava to bring home
1:00 PM2:00 PMLunch at …
3:30 PM8:00 PMOff-Road Dirt Bike Tour in Bahrah
9:00 PM10:00 PMDinner at Al-Romansiah Saudi Restaurant

Sunday, May 18 – Jeddah

Start TimeEnd TimeActivity
Breakfast at … (Shakshouka, Roz Bi-Laban)
8:00 AM11:00 AME-bike along the corniche
12:00 PM1:30 PMLunch at Asli Basha Turkish restaurant
4:00 PM5:00 PMRed Sea Rush Boat Ride
5:00 PM5:30 PMJet skiing in the Red Sea
8:00 PM9:30 PMDinner at Khayal Turkish restaurant

Monday, May 19 – Fly to USA

Start TimeEnd TimeActivity
6:00 AMGo to airport
9:50 AM4:05 PMFly from Jeddah to Los Angeles
4:05 PM6:55 PM3-hour layover in Los Angeles 
6:55 PM8:15 PMFly from Los Angeles to San Francsisco

Saturday, May 10, 2025

Fly from San Francisco to Los Angeles

Fly from Los Angeles to Jeddah, Saudi Arabia

Sunday, May 11, 2025

Drive from Jeddah airport to Luli’s house

Luli’s house

Monday, May 12, 2025

Uber from Luli’s house to Jeddah airport train station

Bullet train from Jeddah to Medina

Lunch at Al Baik – The KFC of Saudi Arabia

BBQ Baik
4-piece chicken meal
Falafel

Visit the Prophet’s Mosque

Bullet Train from Medina to Jeddah

Drive (Uber) from Jeddah airport train station to Nawal’s House

Tuesday, May 13, 2025

Drive from Nawal’s house in Jeddah to Farida’s house in Mecca

Drive to Miqat Tan’im (Masjid Aisha)

Drive to Masjid Al-Haram

Umrah

  1. Go to the miqaat location (per tradition, not Quran)
  2. Wear 2 white pieces of fabric (men only, per tradition, not Quran)
  3. Make the intention to perform Umrah
  4. Recite the Talbiyah
    Labbayka Allahumma labbayk, labbayka la sharika laka labbayk. Inna al-hamd wa\’l-ni\’mata laka wa\’l-mulk, la sharika lak
  5. Go to Masjid Al-Haram
  6. Pray 2 raka’ats
  7. Perform Tawaf (circumambulate the Kaa’ba counterclockwise ) (7x per tradition, 1+x per Quran)
  8. Perform Sa’i (walk between Safa and Marwa starting at Safa) (7x per tradition, 1+x per Quran)
  9. Done

Lunch in Mecca near Masjid Al-Haram

Al Shorfa

Drive (Uber) from Masjid Al Haram to Farida’s House

Drive (Uber) from Farida’s house to train Station

Bullet train from Mecca to Jeddah airport train station

Drive (Uber) from Jeddah airport train station to Tante Zahra & Rushdi’s House

Riyadh’s House

Buy Baklava at بكلافجي

Wednesday, May 14, 2025

Lunch: Saudi Martabak at Ulfat Mutabbaq

  • Google Map
  • Hours: 2 PM – 2 AM
  • Hira St, An Nahdah, Jeddah 23523, Saudi Arabia

Drive to Arabian Treks Campground

Desert Safari

Dune bashing
Sandboarding

Thursday, May 15, 2025

Private Mini Yacht From Jeddah Marina to Bayada Island

Galeon 340 Fly boat
Top deck (seating at top)
Middle deck (seating at back, seating in middle, seating on front deck)
Bottom deck (3 bedrooms, 1 shower room, 1 toilet room)
Middle deck, showing stairs to go to top deck
Middle deck
Middle deck, showing opening to lower deck
Lower deck, master bedroom
Lower deck, 2nd bedroom
Lower deck, 3rd bedroom
Lower deck, shower room
Lower deck, toilet room
  1. Play music using Bose portable speaker
  2. Lip sync Cest La Vie at various scenes
  3. On boat, change into captain outfit and make video tour of the yacht
  4. Take pic looking out using binoculars
  5. Give everyone plastic champagne glasses and pour apple cider
  6. On boat, change into rastafarian hair and make video eating baklava in master bedroom or on front deck of boat
  7. Upon arriving at Bayada, take a group photo using the 10′ selfie stick with everyone standing on the front deck of the boat. Take both a video and interval photos.
  8. Get on inflatable lounger and float around boat while sipping on apple cider
  9. Have Riyadh jump into the water near me to make me fall off the lounge
  10. Take turns jumping into water from boat
  11. Everyone jump into the water at the same time
  12. Go snorkeling

Lebanese Dinner at Al Nakheel Restaurant

  • Google Map
  • Hours: 5 PM – 1 AM
  • حي, Al Kurnaysh Br Rd, Ash Shati, Jeddah 23413, Saudi Arabia
  • Do this at night because there is outdoor seating.

Friday, May 16, 2025

Turkish Lunch at Saraya Latif

Historic Jeddah – Al Balad Walking Tour

This neighborhood is from the 7th century.

Google Map

Bab Makkah – باب مكة

Google Map

Souq Bab Makkah – سوق باب مكه

Google Map

Al-Basali Seafood Restaurant – مطعم البصلي للاسماك والمأكولات البحرية

Google Map
Hours: 1 PM – 11:30 PM

Al-Basali Seafood Restaurant
Al-Basali Seafood Restaurant
Al-Basali Seafood Restaurant
Al-Basali Seafood Restaurant

Souq Al-Badu – سوق البدو

Google Map

Al-Matbouli House – بيت المتبولي

Google Map

Souq Al-Alawi – سوق العلوي

Google Map

Al-Shargi House – البيت الشرقي

Google Map

Zawiya 97 – زاوية ٩٧

Google Map

Nassif House – بيت نصيف

Google Map

Noorwali House – بيت نورولي

Google Map

Jumjoom House – بيت الجمجوم

Google Map

Shaikh Ibrahim Ahmad Abu Hamaa’il House – بيت الشيخ ابراهيم احمد ابو الحمائل

Google Map

Antique Houses

Google Map

Fizwan House – بَيت فَرْوان

Google Map

Jeddah Historic District

Google Map

Roshan Cafe – روشان كافية

Google Map

Have Saudi coffee on the rooftop of Roshan Cafe

Take a picture like this

Baeshan’s House – بيت باعشن

Google Map

Saloom’s House – بيت سلوم

Google Map

Souq Al-Nada – سوق الندى

Google Map

Qabel Trail – شارع قابل

Google Map

The following houses are a little bit out of the way.

Al-Sharbatly House – بيت الشربتلي

Google Map

Barghoutah House – بيت برغوته

Google Map

Walk the Jeddah corniche at night

King Fahd Fountain (turns on at sunset)
Al-Rahmah Floating Mosque
Jeddah Yacht Club and Marina

Saturday, May 17, 2025

Breakfast Buffet at Twenty Four Restaurant

Off-Road Dirt Bike Tour in Bahrah

Bikes

Morning tour: 6 AM – 9 AM
Afternoon tour: 3:30 PM till sunset (7 PM)

Cost: 500 SAR ($133)
Includes bike, helmet, body protection.
Does not include transportation to and from Bahrah.

Contact

  • Hassan Hawsawi
  • WhatsApp: +966 59 006 6986
Yamaha YZ450F
Honda CRF450R
Kawasaki KX 250F
Kawasaki KX 250F

Saudi Dinner at Al-Romansiah Restaurant الرومانسية -البوادي

  • Google Map
  • Hours: 10:30 AM – 12:30 AM
  • Qouraish, Al Bawadi, Jeddah 23443, Saudi Arabia
  • Menu
Chicken Mandi
Chicken Kabsa
Jareesh

Take a picture like this

Sunday, May 18, 2025

E-bike along the corniche

Turkish Lunch at Asli Basha

  • Google Map
  • Hours: 1 PM – 2 AM
  • 8006 صفيه بنت عبدالمطلب, An Naim District, JENF2777، 2777, Jeddah 23621, Saudi Arabia

Red Sea Rush Boat Ride

Jet Skiing in the Red Sea

Ride jetskis along the coast

Turkish Dinner at Khayal Restaurant

  • Location 1 – Al Zahra
  • Location 2 – Outside Cenomi Mall of Arabia
  • Hours: 12:30 PM – 3 AM
  • Menu
    • Cucumber Yogurt Salad
    • Iskander Kebab (beef)
    • Khayal Grill Mix
    • Layers juice
Khayal Grill Mix, Layered Juice Drink, Iskendar Kebab
1/2 meter or 1 meter kabab
Mixed Grill
Iskendar Kebab
Cucumber Yogurt Salad

Monday, May 19, 2025

6:00 AM – Go to airport

Terminal 1

9:50 AM – Fly from Jeddah to Los Angeles

Other Food and Restaurants

Shakshouka

Roz Bi-Laban

Turkish Dinner at Bursa Iskendar

  • Google Map
  • Hours: 12 PM – 2 AM
  • 3195 Muhyi Ad Din An Nadhir, Al-Hamra’a, Jeddah 23212, Saudi Arabia

Pakistani Lamb Chops at Marhaba Restaurant

Kachumber Salad (tomato, cucumber) – 16 SAR – $4.26
Lamb Chops – 55 SAR = $14.66
Kheer – 16 SAR – $4.26

Maison De Zaid دار زيد

Pistachio Pancake – Large fluffy pancake served with pistachio sauce & halwa tahini – 45 SAR = $12

Manahi Restaurant

Saleeg

Hashi Basha (Camel Meat)

A Collection of AI Tools for Various Purposes

This is just a collection of AI tools I’ve used that I’ve found useful. With so many AI tools sprouting up, this list will likely be updated regularly as time permits.

AI Portal

Image Editing

Audio Editing

Speech

Video Editing

Text Editing

  • ChatGPT
  • Grammarly

Code Editing

  • Cursor
  • Bolt.new
  • Bolt.diy
  • Claude 3.7 Code
  • GitHub Copilot
  • Coedium’s Windsurf
  • Locofy.ai
  • Vercel v0
  • Dora.ai
  • Relume
  • replit
  • lovable

Install AI Apps

Color Palette

Virtual Staging

Different Ways to Build a Component-Based Static Website

Static websites are fast and ideal for many types of websites like blogs, marketing websites, and more. When building websites, you should always use a component-based approach for code simplicity, maintenance, and reusability. Here are a few ways to build a static website using components.

  1. Web Components – No framework
  2. Eleventy (11ty) – Very simple and flexible static site generator that supports various template languages (Handlebars, Nunjucks, etc)
  3. Astro – Very similar to Eleventy, with the advantage of being able to load premade components from React, Vue, Svelte, etc.
  4. Svelte – More like React, but better. Outputs static files. Has native benefits like CSS optimizations and the ability to create interactive apps, if necessary.

The following video does a great job in comparing and demonstrating building a static site using web components and Svelte.

FrontLobby: Motivate Tenants to Pay Rent on Time and to Pay Their Rent Debt After Moving Out

I recently rented out an apartment to a new tenant. I created the lease online using Zillow. While Zillow does include mandatory notices and includes a credit score and background check service, it doesn’t mention anything about recommending landlords get certain personally identifying information (PII) that can be critical in helping landlords if a tenant decides to stop paying rent.

In one of my rentals, I inherited a tenant who, after a few years, couldn’t pay the rent. Despite trying to work with her, she clearly knew that she could stay just stop paying and stay in the apartment until she is served a formal eviction notice by the sheriff. Due to court backlogs, it would be about 2 months before the sheriff could serve her, and there was nothing I could do about it. I eventually lost around $5000, but at least I was able to renovate the apartment and rent it out for $500 a month more. Nevertheless, the carelessness of the tenant, who thought she could rip me off, was disturbing, as California law is too lenient on renters. Fortunately, I found a way that could either get the former tenant to pay her debt or suffer the consequences of her non-payment being recorded in her credit history. However, you can’t report your tenant to the credit bureaus unless you have enough information, including their date of birth. Since I didn’t have all that information, I had to do some investigative work using Instant Checkmate and Ancestry.com. With Instant Checkmate, I was able to find all sorts of information about my former tenant, including the fact that she had filed for bankruptcy and had been evicted in the past. Instant Checkmate looks like a super shady website, but luckily, it’s not. With Ancestry.com, I was able to get her date of birth, which is required in order to report people to the credit bureaus. With this information, along with signed copies of the lease and other details, I used a service called FrontLobby to go after my former tenant.

FrontLobby can be used to report current tenants to the credit bureaus when they pay late or don’t pay at all. It can also be used to report former tenants.

New / Existing Tenants

If you will have a new tenant, make sure you get the following information from them before they move in:

  • Legal first, middle, and last names
  • date of birth (required in order to report people to the credit bureaus
  • social security number (for more accurate reporting)
  • email
  • phone number
  • aliases, if any.

I would make a copy of their social security card and driver’s license.

You can then inform your new and existing tenants that you will use FrontLobby to track their rent payments and to automatically notify the credit bureaus if they are late. This should make tenants become more motivated to pay on time. You can also inform tenants that if they pay on time, that could help improve their credit score.

Former Tenants Who Are Delinquent

If your tenant has already moved out and they owe your rent, you can use FrontLobby to report their debt to the credit bureaus.

FrontLobby will first email them an introduction to encourage them to pay their debt.

FrontLobby will send the former tenant up to 3 introduction emails. If the former tenant doesn’t register with FrontLobby, FrontLobby will send monthly emails informing the former tenant that their credit score will continue to be affected until they pay.

Lastly, if the former tenant still doesn’t pay, then they will get an email alerting them that their debt has been registered with the credit bureaus.

Once you activate debt reporting, you’ll see a notice like this:

Using a Grid System for Web Design and Development

I’ve worked with many graphic designers who were tasked with created web designs. Unfortunately, most designers claimed to know web design when in reality they didn’t. This was obvious when they kept asking me for specific width and height dimensions when I’d ask them for a new hero design. Designing for print is much simpler than designing for web. With print, what you see is what you get because there’s only one size and nothing is interactive. When designing for web, there are numerous factors that must be considered, including SEO impact. In this post, I’ll talk about just one aspect of design that all web designers should understand: grid systems.

A grid system is just a bunch of columns and, optionally, rows, that help you arrange your design elements. It’s useful for print design, but I’d argue it is essential for web design. In the New York Times screenshot above, you see a bunch of pink columns separate by white gaps (gutters). Notice how the content blocks fit within the columns. Without those columns, your design could end up with a lot of alignment issues, especially when the design contains a lot more than just a bunch of text blocks. Grid systems don’t just make it easier for designers to align content – they also make it easier for developers to develop responsive pages that match the designs they are provided. That’s why CSS has a display option called “grid” and why Bootstrap, one of the most popular CSS frameworks, offers a grid system with sensible defaults.

The most common grid system is the 12-column grid. If you’re a developer, you don’t have to use CSS grid or a premade system like Bootstrap’s grid system – you can use flexbox to lay out your content. But, I personally think it’s better to use a grid for your main layout and just use flex for sub-layouts, e.g., when you’re laying out content within a grid’s cell. This is particularly helpful because your main layout will need to be responsive, and Bootstrap’s grid system already includes code to make your grid responsive automatically. Additionally, if you are part of a dev team, it’ll be easier to update someone else’s code if everyone follows the same coding convention, like using Bootstrap’s grid classes.

If you use Tailwind CSS, you can easily create a grid system using Tailwind CSS classes. However, you’ll have to define your own breakpoints, e.g., on desktop, show 12 columns, but on mobile, show only one.

The easiest way to demonstrate both Bootstrap’s grid system and creating a grid in Tailwind CSS is by example. If you are a developer, the CodePen below should be self-explanatory. Open each CodePen in a separate tab to see the columns on desktop.

Tailwind CSS

See the Pen Tailwind CSS Layouts by Abdullah Yahya (@javanigus) on CodePen.

Bootstrap

See the Pen Untitled by Abdullah Yahya (@javanigus) on CodePen.