tailwindlabs/tailwindcss-typography

docs: update for Tailwind 4

benmccann opened this issue Β· 40 comments

What version of @tailwindcss/typography are you using?

4.0.0

What version of Node.js are you using?

22.11.0

What browser are you using?

Chrome

What operating system are you using?

Linux

Reproduction repository

https://github.com/tailwindlabs/tailwindcss-typography

Describe your issue

The readme here says Then add the plugin to your tailwind.config.js file, but running pnpx @tailwindcss/upgrade@next as instructed in https://tailwindcss.com/docs/upgrade-guide#using-the-upgrade-tool removed my tailwind.config.js file. The upgrade guide doesn't make any mention of plugins. The readme here doesn't specify if this plugin works with Tailwind 3 and/or 4

The docs for the other plugins such as forms and container queries need to be updated as well

This is what I used in src/app/globals.css

@plugin "@tailwindcss/typography";

WARNING
However tailwindcss docs describes this as for 'legacy' only - which implies that this module ( typgraphy) is now legacy/deprecated - so what is the recommendation for migrating off typography?

It is possible this can work using @import may work instead of @plugin but I have not tried yet.

See tw docs

@gene-git thank you for that. It also works with @plugin "@tailwindcss/forms";, although it does not work with @tailwindcss/postcss as it seems to not have any effect. PostCSS paths fail to be resolved.

It is possible this can work using import instead of plugin but I have not tried yet.

Using @import instead of @plugin fails with Error: Can't resolve '@tailwindcss/typography' in <INSERT YOUR PATH HERE>.

It may also be helpful to include some details on customizing since the docs talk all about using the JS config file instead of theme. For example, what's the best way to set the colors to Slate or Zinc?

There's zero information I can find for plugin developers about how to support v4.

It feels like they were in such a hurry to release it, that pretty simple questions never got answered.

Also wondering why there is no mention of typography and other plugsins here or in the upgrade guide.

I always renamed it to rte, since Shopify is using this as well. Anyone here that knows how to do this with TW 4?

Hopefully they'll offer a CSS stylesheet with the correct utility class definitions.

You can also generate a style sheet via postcss manually - but it won't have the utility class settings via @utility directive.

A bit like @victorelgersma has done here... https://github.com/victorelgersma/tailwind-typography-stylesheet (although prose and other classnames are defined in this stylesheet).

I can also see some mention of typography but I'm not sure if this is how we configure the styles in tailwind typography:

https://tailwindcss.com/docs/theme#with-custom-css

@gene-git thank you for that. It also works with @plugin "@tailwindcss/forms";, although it does not work with @tailwindcss/postcss as it seems to not have any effect. PostCSS paths fail to be resolved.

It is possible this can work using import instead of plugin but I have not tried yet.

Using @import instead of @plugin fails with Error: Can't resolve '@tailwindcss/typography' in <INSERT YOUR PATH HERE>.

@nickjj I think for the postcss you need to add that configuration to the postcss config file.. .postcssrc.json

{  
  "plugins": {
    "@tailwindcss/postcss": {}
  }
}

see: https://tailwindcss.com/docs/installation/framework-guides/angular, this is where I got the reference form.

I recently upgraded Tailwind v3 to v4 and use @tailwindcss/typography

I confirm the use of

@plugin "@tailwindcss/typography" ;

in your main css file

and I looked for a good solution to customize the plugin's theme and finally tried something like this:

/* Typography plugin */
@utility prose {
  --tw-prose-body: var(--color-primary);
  --tw-prose-headings: var(--color-primary);
  --tw-prose-bold: var(--color-primary);
  --tw-prose-quote-borders: var(--color-slate-300);
  --tw-prose-quotes: var(--color-muted-foreground);
  --tw-prose-code: var(--color-primary);

  code {
    &::before,
    &::after {
      display : none ;
    }
    text-wrap : nowrap ;
  }

  blockquote {
    font-weight : 400 ;
  }
}

note, all my custom var() are defined in my @theme and it works the way I want it to

In my current tailwind v3 setup I disable some the typography options. Anyone have any ideas how to this in v4 "natively"?

const disabledCss = {
  'code::before': false,
  'code::after': false,
  'blockquote p:first-of-type::before': false,
  'blockquote p:last-of-type::after': false,
  pre: false,
  code: false,
  'pre code': false,
}

In my current tailwind v3 setup I disable some the typography options. Anyone have any ideas how to this in v4 "natively"?

const disabledCss = {
  'code::before': false,
  'code::after': false,
  'blockquote p:first-of-type::before': false,
  'blockquote p:last-of-type::after': false,
  pre: false,
  code: false,
  'pre code': false,
}

Not possible, you have to override the utility layer yourself in v4 as of now.

@Utility prose {} isn't working my me, instead, i had to put it in the theme file:

@theme {
--color-offWhite: #fcfcfc;
--color-lightGrey: #b5b5b5;
--color-darkGrey: #2d2d2d;
--color-limeGreen: #c6f495;
--color-navyBlue: #060b30;

--aspect-landscape: 36 / 17;
--aspect-portrait: 90 / 67;

--font-sans: 'Sora Variable';
--font-headings: 'DM Sans Variable';

--tw-prose-bullets: var(--colors-limeGreen);
--tw-prose-headings: var(--colors-darkGrey);
--tw-prose-links: var(--colors-navyBlue);
--tw-prose-body: var(--colors-navyBlue);
--tw-prose-invert-body: var(--colors-offWhite);
--tw-prose-invert-bullets: var(--colors-offWhite);
--tw-prose-invert-headings: var(--colors-offWhite);
--tw-prose-invert-links: var(--colors-white);
}

I am finding this works to disable some of the things i was trying to disable (see my previous question):

/*
    Typography plugin configuration
*/
@utility prose {
  code {
    &::before,
    &::after {
      display: none;
    }
  }

  blockquote {
    /* Remove extra quotes */
    p {
      &:first-of-type::before,
      &:last-of-type::after {
        display: none;
      }
    }
  }
}

@Utility prose {} isn't working my me, instead, i had to put it in the theme file:

@theme { --color-offWhite: #fcfcfc; --color-lightGrey: #b5b5b5; --color-darkGrey: #2d2d2d; --color-limeGreen: #c6f495; --color-navyBlue: #060b30;

--aspect-landscape: 36 / 17; --aspect-portrait: 90 / 67;

--font-sans: 'Sora Variable'; --font-headings: 'DM Sans Variable';

--tw-prose-bullets: var(--colors-limeGreen); --tw-prose-headings: var(--colors-darkGrey); --tw-prose-links: var(--colors-navyBlue); --tw-prose-body: var(--colors-navyBlue); --tw-prose-invert-body: var(--colors-offWhite); --tw-prose-invert-bullets: var(--colors-offWhite); --tw-prose-invert-headings: var(--colors-offWhite); --tw-prose-invert-links: var(--colors-white); }

if you are truly capitalizing "Utility" that could be the issue.

Yeah, this plugin not having proper support in v4 is what's holding me back from upgrading to v4.

What about this in TW4?

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      typography: {
        DEFAULT: {
          css: {
            color: '#333',
            a: {
              color: '#3182ce',
              '&:hover': {
                color: '#2c5282',
              },
            },
          },
        },
      },
    },
  },
  plugins: [
    require('@tailwindcss/typography'),
    // ...
  ],
}

In a tweet from @adamwathan a few moments ago:

"[No official update yet] Not yet, it works with v4 as-is but you need to use a JS config if you want to customize it. Hoping to do a CSS-only version in the near-ish future once we’re caught up on bug fixes and stuff."

https://x.com/adamwathan/status/1886899688407699658

In a tweet from @adamwathan a few moments ago:

"[No official update yet] Not yet, it works with v4 as-is but you need to use a JS config if you want to customize it. Hoping to do a CSS-only version in the near-ish future once we’re caught up on bug fixes and stuff."

https://x.com/adamwathan/status/1886899688407699658

I think is is incorrect because the js config doesn't work with typography in v4

@KorigamiK Do you mind to clarify/put together a repro what part is not working? I would expect a config file like this loaded via @config to work as part of our compatibility work. There is no "v4" way of customizing the typography plugin, though, if that's what you mean.

Since there was some confusion on how to use the typography plugin together with Tailwind CSS v4 and the JavaScript-based configuration (as opposed to CSS based overwrites that were already discussed in this thread), I went ahead and created a small Vite project to show you how such a setup can look like: https://github.com/philipp-spiess/tw4-typography-plugin-config/blob/main/src/tailwind.config.js

The main change is to load the typography plugin via an @config file, so in your v4 stylesheet you can do this:

  @import "tailwindcss";
- @plugin "@tailwindcss/typography";
+ @config "./tailwind.config.js";

And then have a tailwind.config.js file like this that uses the JavaScript theme API to load and extend the typography styles:

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      typography: (theme) => ({
        DEFAULT: {
          css: {
            color: theme("--color-neutral-700"),
            a: {
              color: theme("--color-sky-600"),
              "&:hover": {
                color: theme("--color-sky-800"),
              },
            },
          },
        },
      }),
    },
  },
  plugins: [require("@tailwindcss/typography")],
};

I'll also go ahead and update the project REAMDE to make this clearer on Monday, sorry for the confusion here for sure! That said if you find any compatibility issues please feel free to reach out here and ask in the meantime.

/cc @stijns96 since you asked on how to use this kind of setup above πŸ‘

Edit: I want to add that we certainly want to improve this and allow all extended configurations that currently require the JavaScript API to be accessible via CSS only. We're already evaluating internal prototypes for this so hopefully we can get rid of the JavaScript API for the typography plugin soon.

@philipp-spiess can you share the docs for @config directives? I couldn't find them

@KorigamiK It's mentioned in the docs here: https://tailwindcss.com/docs/functions-and-directives#config-directive you can look up the v3 docs for infos on how the JavaScript interface works.

@KorigamiK It's mentioned in the docs here: https://tailwindcss.com/docs/functions-and-directives#config-directive you can look up the v3 docs for infos on how the JavaScript interface works.

Ah I see, although since it is legacy it's not the way we should be configuring it right?

Hey folks! I pushed an update to the project readme to give better example of how to use and configure the extension with Tailwind CSS v4. Hopefully this addresses all your concerns!

web-1      |  β¨― ./app/globals.css
web-1      | Error evaluating Node.js code
web-1      | Error: Package path ./typography is not exported from package /app/node_modules/tailwindcss (see exports field in /app/node_modules/tailwindcss/package.json)
web-1      |     [at /app/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js:117:7]
web-1      |     [at Hook.eval [as callAsync] (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10)]
web-1      |     [at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/app/node_modules/tapable/lib/Hook.js:18:14)]
web-1      |     [at Resolver.doResolve (/app/node_modules/enhanced-resolve/lib/Resolver.js:715:16)]
web-1      |     [at /app/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:76:17]
web-1      |     [at /app/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:148:13]
web-1      |     [at /app/node_modules/enhanced-resolve/lib/forEachBail.js:39:13]
web-1      |     [at onJson (/app/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:133:6)]
web-1      |     [at /app/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:86:7]
web-1      |     [at SyncAsyncFileSystemDecorator.readJson (/app/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js:172:6)]
web-1      |

next.js 15 with turbopack

It looks like the docs are missing the @.
The docs at https://tailwindcss.com/docs/functions-and-directives#plugin-directive show it with but the new docs show it without.

Huh yes it should definitely be @tailwindcss/typography, that's the name of the npm package! We fixed the README a couple of days ago but please let me know if you still find my typo somewhere πŸ˜…

I'm still a bit confused as to whether the whole @tailwindcss/typography plugin is considered legacy and deprecated or not. The readme doesn't say anything about it being so, but the docs for @plugin state that directive is for loading legacy plugins. If it is legacy, how should users migrate away from it?

I agree with @benmccann It would be helpful if there was a clearer explanation or ideally a road map for v4 migration

@benmccann I agree the wording around @plugin is a bit confusing. We mention the legacy JavaScript plugin API because we've since added CSS-based options to author utilities and variants and we want lead authors of new extensions towards these APIs instead.

The Typography plugin is still considered first-party and supported. We are working on some updates that will move it to use a CSS based API but this while investigating this we reached some roadblocks and we don't want to offer a watered-down version.

@benmccann I agree the wording around @plugin is a bit confusing. We mention the legacy JavaScript plugin API because we've since added CSS-based options to author utilities and variants and we want lead authors of new extensions towards these APIs instead.

The Typography plugin is still considered first-party and supported. We are working on some updates that will move it to use a CSS based API but this while investigating this we reached some roadblocks and we don't want to offer a watered-down version.

@philipp-spiess is there a guide or a plugin that uses this css based api? I was looking into updating my plugins but I couldn't find any resources or examples on the docs or the tailwindlabs org.

@hacknug Check out https://tailwindcss.com/docs/adding-custom-styles#adding-custom-utilities

@philipp-spiess but what should plugin authors do? Provide a .css file and ask users to use @import? That page mentions plugins on the opening paragraphs but there is no other mention as to how one would author a plugin for v4, only that the js api is legacy.

@hacknug Yeah, the idea is that plugins provide a .css file for users to @import, exactly. This file can then add new theme variables, provide variants and utilities, and even use the old JS plugin API via adding @plugin calls.

Agree that this should be better explained in the docs, thanks for the feedback! I'll see if I can add something πŸ‘

This file can then […] even use the old JS plugin API via adding @plugin calls

This doesn’t solve things for plugins that took user options right? Like if you used to do plugin({ accentColor: 'red' }) or whatever and then some JS under-the-hood updated Tailwind based on those options, how would a plugin do that with v4?