Labnotes

🍫 tidbits

If you want TypeScript types for your TailwindCSS configuration and theme, add JavaScript type annotations in tailwind.config.js, for example:

/**
 * @type {import('tailwindcss/tailwind-config').TailwindConfig & {
 *   theme: {
 *     fontFamily: {
 *       mono: string
 *       sans: string
 *     }
 *   }
 * }}
 */
module.exports = {
  content: ["./app/**/*.{js,ts,jsx,tsx}"],
  theme: {
    fontFamily: {
      sans: "Inter, Helvetica, sans-serif",
      mono: "Fira Sans, Monaco, Courier, monospace",
    },
  },
};

You can then import these types and apply them to the resulting Tailwind theme:

import resolveConfig from "tailwindcss/resolveConfig";
import tailwindConfig from "../tailwind.config.js";

const tailwind = resolveConfig(tailwindConfig) as typeof tailwindConfig;

Note that a theme (tailwind variable here) is a transformation of the configuration (module.exports). The final type you want is the theme, not the configuration. In this example, they're both the same.

(2022-06-13)


Tailwind and Mantine conflict with each other. You have two options:

  1. Tell Mantine to append CSS styles, so they over-ride TailwindCSS
  2. Disable Tailwind preflight (CSS reset)

Mantine has its own CSS reset (withNormalizeCSS), so you might as well use that, and disable preflight: https://tailwindcss.com/docs/preflight#disabling-preflight.

Alternatively, you can provide Mantine with an Emotion cache, that has prepend: false, so Mantine CSS loads after Tailwind.

(2022-07-25 updated)


You can get the current timezone for a website visitor with:

Intl.DateTimeFormat().resolvedOptions().timeZone;

Supported in all the modern browsers.

(2020-03-22)


If you're using esbuild to bundle a Node module into ESM, you may run into an error that looks like this:

throw new Error('Dynamic require of "' + x2 + '" is not supported');

ESM Node modules do not have access to require. You're seeing this error either because your code is using require, or more likely, your code imports 3rd party module that uses require.

At which point you have two options:

// require_shim.js
import { createRequire } from "module";
global.require = createRequire(import.meta.url);

(2021-01-08)


If you're using Docusaurus.io, and you see this error when running npx docusaurus build, make sure you have a static directory.

ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns should be a non-empty array.

mkdir static
touch static/.empty

(2022-01-03)