Skip to content

feat: Smartypants config#15340

Merged
matthewp merged 16 commits intowithastro:mainfrom
trueberryless:feat/smartypants-config-options
Mar 25, 2026
Merged

feat: Smartypants config#15340
matthewp merged 16 commits intowithastro:mainfrom
trueberryless:feat/smartypants-config-options

Conversation

@trueberryless
Copy link
Copy Markdown
Contributor

@trueberryless trueberryless commented Jan 29, 2026

Changes

Adapt markdown.smartypants configuration to allow passing more detailed object.

I added a new dependency, thanks to @ArmandPhilippot's suggest: retext-smartypants as this allows us to use the SmartypantsOptions necessary for this feature without reimplementing them. The zod schema still needs a little bit of redundancy tho.

Related: withastro/roadmap#1027

Testing

Added new e2e test cases covering some of the options, as I think the remark-smartypants plugin should verify that all options work, so therefore, not all are covered here.

Docs

I adapted the https://github.com/withastro/astro/blob/main/packages/astro/src/types/public/config.ts file which will autogenerate the new configuration reference.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jan 29, 2026

🦋 Changeset detected

Latest commit: 179938e

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added feat: markdown Related to Markdown (scope) pkg: astro Related to the core `astro` package (scope) docs pr labels Jan 29, 2026
@trueberryless trueberryless changed the title feat(markdown/remark): Smartypants config feat: Smartypants config Jan 29, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Jan 29, 2026

Merging this PR will not alter performance

✅ 18 untouched benchmarks


Comparing trueberryless:feat/smartypants-config-options (179938e) with main (ee3ab41)

Open in CodSpeed

@Princesseuh
Copy link
Copy Markdown
Member

Awesome work! This is very nice. Unless something special happens, 5.17 was the last minor for the 5.x series of Astro. Would you be willing to rebase this PR onto the next branch? This would be released as part of Astro 6.

@Princesseuh Princesseuh modified the milestone: v6.0.0 Jan 29, 2026
@trueberryless trueberryless changed the base branch from main to next January 30, 2026 07:36
@trueberryless trueberryless force-pushed the feat/smartypants-config-options branch from 131cd45 to 4f302de Compare January 30, 2026 07:36
@trueberryless
Copy link
Copy Markdown
Contributor Author

trueberryless commented Jan 30, 2026

Awesome work! This is very nice. Unless something special happens, 5.17 was the last minor for the 5.x series of Astro. Would you be willing to rebase this PR onto the next branch? This would be released as part of Astro 6.

Thanks for letting me know, rebase is done!

EDIT: Just some type errors to fix for me so the tests pass again 👍

EDIT 2: Actually, I am really not sure how to fix this error. It seems like a mismatch with undefined.
Currently there is .default(ASTRO_CONFIG_DEFAULTS.markdown.smartypants) which should resolve to true, but it fails to build. However, when I hard-code true it would work. I am a little bit confused by this 🤔

Do you know how to fix this, Erika?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 30, 2026

e18e dependency analysis

No dependency warnings found.

@matthewp matthewp deleted the branch withastro:main January 30, 2026 17:31
@matthewp matthewp closed this Jan 30, 2026
@matthewp matthewp reopened this Jan 30, 2026
@florian-lefebvre florian-lefebvre changed the base branch from next to main February 17, 2026 07:38
@Princesseuh Princesseuh added this to the 6.1 milestone Mar 18, 2026
@ArmandPhilippot
Copy link
Copy Markdown
Member

Thanks, Felix! I was checking the JSDoc and it seems a bit tedious to duplicate the retext-smartypants docs... What if tomorrow retext-smartypants adds/removes some options. I don't think this our role to describe what is available there.

Because retext-smartypants provides their own JSDoc and is already pulled by remark-smartypants, I wonder if it wouldn't make more sense to install it as a direct dependency. Then we could simply use:

import type { Options as SmartypantsOptions } from "retext-smartypants";
/* ... */
export interface AstroMarkdownOptions {
	syntaxHighlight?: SyntaxHighlightConfig | SyntaxHighlightConfigType | false;
	shikiConfig?: ShikiConfig;
	remarkPlugins?: RemarkPlugins;
	rehypePlugins?: RehypePlugins;
	remarkRehype?: RemarkRehype;
	gfm?: boolean;
	smartypants?: boolean | SmartypantsOptions;
}

Maybe I miss something, but docs-wise this makes more sense to me to provide a direct link to https://github.com/retextjs/retext-smartypants?tab=readme-ov-file#fields.

Copy link
Copy Markdown
Member

@yanthomasdev yanthomasdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @trueberryless, the changesets look good to me. I agree with Armand's comment, I guess we could explore this option, what you think?

@trueberryless
Copy link
Copy Markdown
Contributor Author

Thanks @ArmandPhilippot for the idea, I really would like to work on this before merging, as this was actually a pain point for me here (duplicating everything), but I didn't think about just installing the dependency to get the option type 💛

Also thanks @yanthomasdev for the ping!

@trueberryless trueberryless marked this pull request as draft March 25, 2026 13:53
@trueberryless trueberryless marked this pull request as ready for review March 25, 2026 15:31
@trueberryless
Copy link
Copy Markdown
Contributor Author

The one failing test seems to be a timeout issue. Can someone with permissions please retry?
@ArmandPhilippot I implemented your suggestion, feel free to review again (no rush tho).

@trueberryless trueberryless requested a review from ematipico March 25, 2026 15:32
Copy link
Copy Markdown
Member

@ArmandPhilippot ArmandPhilippot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @trueberryless! Docs-wise and maintenance-wise, this looks much better to me! 🙌🏽

Edit: The failing test is rerunning!

Co-authored-by: Armand Philippot <git@armand.philippot.eu>
@matthewp matthewp merged commit 10a1a5a into withastro:main Mar 25, 2026
27 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Mar 25, 2026
dadezzz pushed a commit to dadezzz/ice-notes that referenced this pull request Mar 30, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`6.0.8` → `6.1.1`](https://renovatebot.com/diffs/npm/astro/6.0.8/6.1.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/astro/6.1.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/astro/6.0.8/6.1.1?slim=true) |

---

### Release Notes

<details>
<summary>withastro/astro (astro)</summary>

### [`v6.1.1`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#611)

[Compare Source](https://github.com/withastro/astro/compare/astro@6.1.0...astro@6.1.1)

##### Patch Changes

- [#&#8203;16105](withastro/astro#16105) [`23d60de`](withastro/astro@23d60de) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fix dev toolbar audit crash when encountering the `image` ARIA role

- [#&#8203;16089](withastro/astro#16089) [`999c875`](withastro/astro@999c875) Thanks [@&#8203;martrapp](https://github.com/martrapp)! - Fixes an issue with the client router where Vue's `:deep()` notation was ignored in dev mode.

### [`v6.1.0`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#610)

[Compare Source](https://github.com/withastro/astro/compare/astro@6.0.8...astro@6.1.0)

##### Minor Changes

- [#&#8203;15804](withastro/astro#15804) [`a5e7232`](withastro/astro@a5e7232) Thanks [@&#8203;merlinnot](https://github.com/merlinnot)! - Allows setting codec-specific defaults for Astro's built-in Sharp image service via `image.service.config`.

  You can now configure encoder-level options such as `jpeg.mozjpeg`, `webp.effort`, `webp.alphaQuality`, `avif.effort`, `avif.chromaSubsampling`, and `png.compressionLevel` when using `astro/assets/services/sharp` for compile-time image generation.

  These settings apply as defaults for the built-in Sharp pipeline, while per-image `quality` still takes precedence when set on `<Image />`, `<Picture />`, or `getImage()`.

- [#&#8203;15455](withastro/astro#15455) [`babf57f`](withastro/astro@babf57f) Thanks [@&#8203;AhmadYasser1](https://github.com/AhmadYasser1)! - Adds `fallbackRoutes` to the `IntegrationResolvedRoute` type, exposing i18n fallback routes to integrations via the `astro:routes:resolved` hook for projects using `fallbackType: 'rewrite'`.

  This allows integrations such as the sitemap integration to properly include generated fallback routes in their output.

  ```js
  {
    'astro:routes:resolved': ({ routes }) => {
      for (const route of routes) {
        for (const fallback of route.fallbackRoutes) {
          console.log(fallback.pathname) // e.g. /fr/about/
        }
      }
    }
  }
  ```

- [#&#8203;15340](withastro/astro#15340) [`10a1a5a`](withastro/astro@10a1a5a) Thanks [@&#8203;trueberryless](https://github.com/trueberryless)! - Adds support for advanced configuration of SmartyPants in Markdown.

  You can now pass an options object to `markdown.smartypants` in your Astro configuration to fine-tune how punctuation, dashes, and quotes are transformed.

  This is helpful for projects that require specific typographic standards, such as "oldschool" dash handling or localized quotation marks.

  ```js
  // astro.config.mjs
  export default defineConfig({
    markdown: {
      smartypants: {
        backticks: 'all',
        dashes: 'oldschool',
        ellipses: 'unspaced',
        openingQuotes: { double: '«', single: '‹' },
        closingQuotes: { double: '»', single: '›' },
        quotes: false,
      },
    },
  });
  ```

  See [the `retext-smartypants` options](https://github.com/retextjs/retext-smartypants?tab=readme-ov-file#fields) for more information.

##### Patch Changes

- [#&#8203;16025](withastro/astro#16025) [`a09f319`](withastro/astro@a09f319) Thanks [@&#8203;koji-1009](https://github.com/koji-1009)! - Instructs the client router to skip view transition animations when the browser is already providing its own visual transition, such as a swipe gesture.

- [#&#8203;16055](withastro/astro#16055) [`ccecb8f`](withastro/astro@ccecb8f) Thanks [@&#8203;Gautam-Bharadwaj](https://github.com/Gautam-Bharadwaj)! - Fixes an issue where `client:only` components could have duplicate `client:component-path` attributes added in MDX in rare cases

- [#&#8203;16081](withastro/astro#16081) [`44fc340`](withastro/astro@44fc340) Thanks [@&#8203;crazylogic03](https://github.com/crazylogic03)! - Fixes the `emitFile() is not supported in serve mode` warning that appears during `astro dev` when using integrations that inject before-hydration scripts (e.g. `@astrojs/react`)

- [#&#8203;16068](withastro/astro#16068) [`31d733b`](withastro/astro@31d733b) Thanks [@&#8203;Karthikeya1500](https://github.com/Karthikeya1500)! - Fixes the dev toolbar a11y audit incorrectly classifying `menuitemradio` as a non-interactive ARIA role.

- [#&#8203;16080](withastro/astro#16080) [`e80ac73`](withastro/astro@e80ac73) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixes `experimental.queuedRendering` incorrectly escaping the HTML output of `.html` page files, causing the page content to render as plain text instead of HTML in the browser.

- [#&#8203;16048](withastro/astro#16048) [`13b9d56`](withastro/astro@13b9d56) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes a dev server crash (`serverIslandNameMap.get is not a function`) that occurred when navigating to a page with `server:defer` after first visiting a page without one, when using `@astrojs/cloudflare`

- [#&#8203;16093](withastro/astro#16093) [`336e086`](withastro/astro@336e086) Thanks [@&#8203;Snugug](https://github.com/Snugug)! - Fixes Zod meta not correctly being rendered on top-level schema when converted into JSON Schema

- [#&#8203;16043](withastro/astro#16043) [`d402485`](withastro/astro@d402485) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixes `checkOrigin` CSRF protection in `astro dev` behind a TLS-terminating reverse proxy. The dev server now reads `X-Forwarded-Proto` (gated on `security.allowedDomains`, matching production behaviour) so the constructed request origin matches the `https://` origin the browser sends. Also ensures `security.allowedDomains` and `security.checkOrigin` are respected in dev.

- [#&#8203;16064](withastro/astro#16064) [`ba58e0d`](withastro/astro@ba58e0d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Updates the dependency `svgo` to the latest, to fix a security issue.

- [#&#8203;16007](withastro/astro#16007) [`2dcd8d5`](withastro/astro@2dcd8d5) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes a case where fonts files would unecessarily be copied several times during the build

- [#&#8203;16017](withastro/astro#16017) [`b089b90`](withastro/astro@b089b90) Thanks [@&#8203;felmonon](https://github.com/felmonon)! - Fix the `astro sync` error message when `getImage()` is called while loading content collections.

- [#&#8203;16014](withastro/astro#16014) [`fa73fbb`](withastro/astro@fa73fbb) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes a build error where using `astro:config/client` inside a `<script>` tag would cause Rollup to fail with "failed to resolve import `virtual:astro:routes` from `virtual:astro:manifest`"

- [#&#8203;16054](withastro/astro#16054) [`f74465a`](withastro/astro@f74465a) Thanks [@&#8203;seroperson](https://github.com/seroperson)! - Fixes an issue with the development server, where changes to the middleware weren't picked, and it required a full restart of the server.

- [#&#8203;16033](withastro/astro#16033) [`198d31b`](withastro/astro@198d31b) Thanks [@&#8203;adampage](https://github.com/adampage)! - Fixes a bug where the the role `image` was incorrectly reported by audit tool bar.

- [#&#8203;15935](withastro/astro#15935) [`278828c`](withastro/astro@278828c) Thanks [@&#8203;oliverlynch](https://github.com/oliverlynch)! - Fixes cached assets failing to revalidate due to redirect check mishandling Not Modified responses.

- [#&#8203;16075](withastro/astro#16075) [`2c1ae85`](withastro/astro@2c1ae85) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes a case where invalid URLs would be generated in development when using font families with an oblique `style` and angles

- [#&#8203;16062](withastro/astro#16062) [`87fd6a4`](withastro/astro@87fd6a4) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Warns on dev server startup when Vite 8 is detected at the top level of the user's project, and automatically adds a `"overrides": { "vite": "^7" }` entry to `package.json` when running `astro add cloudflare`. This prevents a `require_dist is not a function` crash caused by a Vite version split between Astro (requires Vite 7) and packages like `@tailwindcss/vite` that hoist Vite 8.

- Updated dependencies \[[`10a1a5a`](withastro/astro@10a1a5a)]:
  - [@&#8203;astrojs/markdown-remark](https://github.com/astrojs/markdown-remark)@&#8203;7.1.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My44Ni4wIiwidXBkYXRlZEluVmVyIjoiNDMuODYuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: Renovate Bot <renovate@zarantonello.dev>
Co-committed-by: Renovate Bot <renovate@zarantonello.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs pr feat: markdown Related to Markdown (scope) pkg: astro Related to the core `astro` package (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants