Categories
Uncategorised

Pass custom headers to `rewrites` proxy

Found a nice and tidy way to add custom headers to the rewrites proxy if you know next.config.js well.

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export const config = {
  matcher: '/product/:path',
};

// Proxies /product/:id to https://my-proxied-site.com/product/:id
export function middleware(request: NextRequest) {
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('Authorization', 'Bearer ******');

  // Extract product id from pathname
  const [, , id] = request.nextUrl.pathname.split('/');
  request.nextUrl.href = `https://vercel.com/product/${id}`;

  return NextResponse.rewrite(request.nextUrl, {
    request: {
      headers: requestHeaders,
    },
  });
}

A idea from Github: https://github.com/vercel/next.js/discussions/19078

Categories
Uncategorised

How `parse` works – date-fns ?

const dateStr = '2023-02-22'
const dateFormat = 'yyyy-MM-dd'
const newDate = format(new Date(dateStr))
const parsedDate = format(parse(dateStr, dateFormat, new Date()))

It’s quite an exciting thing that I found recently. parse function in date-fns is doing a kind of “character for-loop” to match the date format that you provided and then adjusting the timezone offset for you. This is why it’s the main reason why the date newDate and parsedDate are getting created differently.

function parse(dateString, formatString, referenceDate) {
  const formatParts = formatString.split(/[\s-/:]+/);
  const dateParts = dateString.split(/[\s-/:]+/);

  let year, month, day, hour, minute, second;

  for (let i = 0; i < formatParts.length; i++) {
    const formatPart = formatParts[i];
    const datePart = dateParts[i];

    if (formatPart === 'yyyy') {
      year = parseInt(datePart, 10);
    } else if (formatPart === 'MM') {
      month = parseInt(datePart, 10) - 1;
    } else if (formatPart === 'dd') {
      day = parseInt(datePart, 10);
    } else if (formatPart === 'HH') {
      hour = parseInt(datePart, 10);
    } else if (formatPart === 'mm') {
      minute = parseInt(datePart, 10);
    } else if (formatPart === 'ss') {
      second = parseInt(datePart, 10);
    }
  }

  console.log(year, month, day, hour, minute, second);
  const date = new Date(year, month, day, hour, minute, second);

  if (referenceDate) {
    const timeZoneOffset = referenceDate.getTimezoneOffset();
    const referenceTimestamp = referenceDate.getTime();

    return new Date(referenceTimestamp + timeZoneOffset * 60 * 1000);
  }

  return date;
}
Categories
Uncategorised

`baseUrl` and `include` in tsconfig.json

// Working one
{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "./",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "removeComments": true,
    "strict": true,
    "target": "es6"
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}
// Broken one
{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "removeComments": true,
    "strict": true,
    "target": "es6"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Something interesting that I found. Be careful when you are “playing” with the param baseUrl and include. It might show the message Compiling with Typescript… but it’s not compiling anything because you are in the folder with a path like ./src/src.

Categories
Uncategorised

How to change Arch on M1 ?

#arch to x86
function archx86 {
  if [ $(arch) = "arm64" ];
  then
    exec arch -x86_64 $SHELL
  fi
}

#arch to arm
function archarm {
  if [ $(arch) = "i386" ];
  then
    exec arch -arm64 $SHELL
  fi
}
Categories
Uncategorised

Next.js

A react framework can do static and server-side rendering. Automatic code split feature compile and export into chunks by each page entry points. So pages only loads the required code in order to improve the application’s initial load. Also prefetch is a nice feature happens in the background. Any <Link /> that is in the viewport (initially or through scroll) will be preloaded.

Data Fetching

It supports CSR, SSR, SSG and ISR(Incremental Static Regeneration).

We should use getStaticProps and getStaticPaths, if:

  • Get required data needs to be available at build time, is ahead of user’s request.
  • Good example: Data coming from headless CMS.
  • Pages must be pre-rerendered (for SEO) and be very fast. Because it generates HTML and JSON files which can be cached by CDN for better performance.
  • Non user-specifc data want to be cached.
export const Post = ({ post }) => {
  const router = useRouter()

  if (router.isFallback) {
    return <div>Loading...</div>
  }

  return (
    <>
      <h2>
        {post.id} {post.title}
      </h2>
      <p>{post.body}</p>
    </>
  )
}

export async function getStaticProps(context) {
  const { params } = context
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${params.postId}`
  )
  const data = await response.json()

  if (!data.id) {
    return {
      notFound: true
    }
  }

  console.log(`Generating page for /posts/${params.postId}`)
  return {
    props: {
      post: data
    }
  }
}

export async function getStaticPaths() {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts')
    const data = await response.json()
    const paths = data.map(post => {
      return {
        params: { postId: `${post.id}` }
      }
  })
  return {
    paths: [
      { params: { postId: '1' } },
      { params: { postId: '2' } },
      { params: { postId: '3' } }
    ],
    fallback: true
  }
}

getStaticProps

Next.js will pre-render this page at build time using the props returned by getStaticProps.

getStaticPaths

When you export a function called getStaticPaths (Static Site Generation) from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by getStaticPaths.

getServerSideProps

When getServerSideProps exports as a standalone function, we can fetch those data must be fetched at request time (such as authorization or geo location). It runs only on the server-side and these data only be cached if “cache-control” headers are configured.

You can consider it’s a way to grab

Build-in CSS support

It allows you to import the CSS from a javascript file without extra configuration. The CSS from “node_modules” can simply import like below.

// pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

CSS modules, sass, and less are also supported.

Image component and Image optimization

It offered a next/image component, is a expansion of the HTML <img> element. The image optimization can do resizing and serving the modern image format webp. It avoids transfer huge pictures with a smaller viewport. With the default “intrinsic” layout, images will scale the dimensions down for smaller viewports, but remain the original demensions for larger viewports. The optimization works with any picture rouce, no matter it’s from local or external.

  • Improve performance: images can be resized and encoded on demand, or even it’s from external. It avoids unnecessary steps for creating different sizes of images.
  • Responsiveness: images can be resized based on the screen size.
  • Visual stability: the cumulative layout shift problem is automatically avoided. It’s a layout shift common issue.
  • Faster page load: Next.js images will only be loaded when entering the viewport, being lazy-loaded by default.
  • Better Google search rankings.

Middleware

Next.js Middleware allows you to run the code before a request is completed, then based on the incoming request, you can modify the response by rewriting, redirecting, adding headers, or setting cookies.

Cick for more stuff about how to use it.

Categories
Uncategorised

Git Configurations

Pull with Rebase

Git push with rebase instead of “merge”.

git config --global pull.rebase true

Push only to the current branch.

If its named upstream is identical

git config –global push.default simple