Fix markdown encoding as utf-8 by default
This commit is contained in:
parent
9cd6a6657b
commit
9884738094
10 changed files with 92 additions and 15 deletions
5
.changeset/olive-laws-work.md
Normal file
5
.changeset/olive-laws-work.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix markdown page encoding to be utf-8 by default (same as Astro 2)
|
|
@ -63,6 +63,11 @@ export async function renderPage(
|
||||||
body = encoder.encode(body);
|
body = encoder.encode(body);
|
||||||
headers.set('Content-Length', body.byteLength.toString());
|
headers.set('Content-Length', body.byteLength.toString());
|
||||||
}
|
}
|
||||||
|
// TODO: Revisit if user should manually set charset by themselves in Astro 4
|
||||||
|
// This code preserves the existing behaviour for markdown pages since Astro 2
|
||||||
|
if (route?.component.endsWith('.md')) {
|
||||||
|
headers.set('Content-Type', 'text/html; charset=utf-8');
|
||||||
|
}
|
||||||
const response = new Response(body, { ...init, headers });
|
const response = new Response(body, { ...init, headers });
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,31 @@ import * as cheerio from 'cheerio';
|
||||||
import { loadFixture } from './test-utils.js';
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
describe('Astro basics', () => {
|
describe('Astro basics', () => {
|
||||||
|
/** @type {import('./test-utils').Fixture} */
|
||||||
let fixture;
|
let fixture;
|
||||||
let previewServer;
|
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
fixture = await loadFixture({
|
fixture = await loadFixture({
|
||||||
root: './fixtures/astro-basic/',
|
root: './fixtures/astro-basic/',
|
||||||
});
|
});
|
||||||
await fixture.build();
|
|
||||||
previewServer = await fixture.preview();
|
|
||||||
});
|
|
||||||
|
|
||||||
// important: close preview server (free up port and connection)
|
|
||||||
after(async () => {
|
|
||||||
await previewServer.stop();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('build', () => {
|
describe('build', () => {
|
||||||
|
let previewServer;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
root: './fixtures/astro-basic/',
|
||||||
|
});
|
||||||
|
await fixture.build();
|
||||||
|
previewServer = await fixture.preview();
|
||||||
|
});
|
||||||
|
|
||||||
|
// important: close preview server (free up port and connection)
|
||||||
|
after(async () => {
|
||||||
|
await previewServer.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it('Can load page', async () => {
|
it('Can load page', async () => {
|
||||||
const html = await fixture.readFile(`/index.html`);
|
const html = await fixture.readFile(`/index.html`);
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
|
@ -108,6 +116,18 @@ describe('Astro basics', () => {
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
expect($('#rendered-order').text()).to.eq('Rendered order: A, B');
|
expect($('#rendered-order').text()).to.eq('Rendered order: A, B');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders markdown in utf-8 by default', async () => {
|
||||||
|
const html = await fixture.readFile('/chinese-encoding-md/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('h1').text()).to.equal('我的第一篇博客文章');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders MDX in utf-8 by default', async () => {
|
||||||
|
const html = await fixture.readFile('/chinese-encoding-mdx/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('h1').text()).to.equal('我的第一篇博客文章');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Supports void elements whose name is a string (#2062)', async () => {
|
it('Supports void elements whose name is a string (#2062)', async () => {
|
||||||
|
@ -143,4 +163,40 @@ describe('Astro basics', () => {
|
||||||
expect(result.status).to.equal(404);
|
expect(result.status).to.equal(404);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('development', () => {
|
||||||
|
/** @type {import('./test-utils').DevServer} */
|
||||||
|
let devServer;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
devServer = await fixture.startDevServer();
|
||||||
|
});
|
||||||
|
after(async () => {
|
||||||
|
await devServer.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Renders markdown in utf-8 by default', async () => {
|
||||||
|
const res = await fixture.fetch('/chinese-encoding-md');
|
||||||
|
expect(res.status).to.equal(200);
|
||||||
|
const html = await res.text();
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('h1').text()).to.equal('我的第一篇博客文章');
|
||||||
|
const isUtf8 =
|
||||||
|
res.headers.get('content-type').includes('charset=utf-8') ||
|
||||||
|
html.includes('<meta charset="utf-8">');
|
||||||
|
expect(isUtf8).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Renders MDX in utf-8 by default', async () => {
|
||||||
|
const res = await fixture.fetch('/chinese-encoding-mdx');
|
||||||
|
expect(res.status).to.equal(200);
|
||||||
|
const html = await res.text();
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('h1').text()).to.equal('我的第一篇博客文章');
|
||||||
|
const isUtf8 =
|
||||||
|
res.headers.get('content-type').includes('charset=utf-8') ||
|
||||||
|
html.includes('<meta charset="utf-8">');
|
||||||
|
expect(isUtf8).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
import preact from '@astrojs/preact';
|
import preact from '@astrojs/preact';
|
||||||
|
import mdx from '@astrojs/mdx';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [preact()],
|
integrations: [preact(), mdx()],
|
||||||
// make sure CLI flags have precedence
|
// make sure CLI flags have precedence
|
||||||
server: () => ({ port: 4321 })
|
server: () => ({ port: 4321 })
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@astrojs/mdx": "workspace:*",
|
||||||
"@astrojs/preact": "workspace:*",
|
"@astrojs/preact": "workspace:*",
|
||||||
"astro": "workspace:*",
|
"astro": "workspace:*",
|
||||||
"preact": "^10.17.1"
|
"preact": "^10.17.1"
|
||||||
|
|
3
packages/astro/test/fixtures/astro-basic/src/pages/chinese-encoding-md.md
vendored
Normal file
3
packages/astro/test/fixtures/astro-basic/src/pages/chinese-encoding-md.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# 我的第一篇博客文章
|
||||||
|
|
||||||
|
发表于:2022-07-01
|
3
packages/astro/test/fixtures/astro-basic/src/pages/chinese-encoding-mdx.mdx
vendored
Normal file
3
packages/astro/test/fixtures/astro-basic/src/pages/chinese-encoding-mdx.mdx
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# 我的第一篇博客文章
|
||||||
|
|
||||||
|
发表于:2022-07-01
|
|
@ -90,7 +90,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const PageModule = createAstroModule(Page);
|
const PageModule = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.astro' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
||||||
mod: PageModule,
|
mod: PageModule,
|
||||||
|
@ -171,7 +171,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const PageModule = createAstroModule(Page);
|
const PageModule = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.astro' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
||||||
env,
|
env,
|
||||||
|
@ -218,7 +218,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const PageModule = createAstroModule(Page);
|
const PageModule = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.astro' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
links: [{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }],
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -45,7 +45,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const mod = createAstroModule(Page);
|
const mod = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.mdx' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
env,
|
env,
|
||||||
mod,
|
mod,
|
||||||
|
@ -91,7 +91,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const mod = createAstroModule(Page);
|
const mod = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.mdx' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
env,
|
env,
|
||||||
mod,
|
mod,
|
||||||
|
@ -117,7 +117,7 @@ describe('core/render', () => {
|
||||||
|
|
||||||
const mod = createAstroModule(Page);
|
const mod = createAstroModule(Page);
|
||||||
const ctx = await createRenderContext({
|
const ctx = await createRenderContext({
|
||||||
route: { type: 'page', pathname: '/index' },
|
route: { type: 'page', pathname: '/index', component: 'src/pages/index.mdx' },
|
||||||
request: new Request('http://example.com/'),
|
request: new Request('http://example.com/'),
|
||||||
env,
|
env,
|
||||||
mod,
|
mod,
|
||||||
|
|
|
@ -1747,6 +1747,9 @@ importers:
|
||||||
|
|
||||||
packages/astro/test/fixtures/astro-basic:
|
packages/astro/test/fixtures/astro-basic:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@astrojs/mdx':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../../../integrations/mdx
|
||||||
'@astrojs/preact':
|
'@astrojs/preact':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../../../integrations/preact
|
version: link:../../../../integrations/preact
|
||||||
|
|
Loading…
Reference in a new issue