Учебники Svelte по Markdown, которые я видел, предполагают, что у вас есть доступ к файлу .md
или вы пишете Markdown непосредственно в предварительно обработанном файле.
А что если вы хотите отобразить необработанную строку, содержащую Markdown? Пример использования: Вам нужна гибкость, чтобы иметь возможность обслуживать содержимое в формате Markdown из CMS (например, Strapi) без необходимости вносить изменения в файл .md
.
Есть несколько способов добиться этого, в данном решении мы будем использовать mdsvex
для преобразования Markdown в HTML формат, а затем для рендеринга HTML. mdsvex
— это препроцессор Markdown, который по сути является оберткой для MDX, что делает его совместимым со Svelte.
Установка
Если вы не используете SvelteKit, ознакомьтесь с документацией по MDsveX для альтернативной установки, если используете:
Начните с установки его как dev-зависимости.
npm i --save-dev mdsvex
или…
yarn add --dev mdsvex
Затем обновите конфигурацию Svelte, включив в нее массив extensions
:
(Мы будем использовать файл .svelte
, но вы также можете включить расширения, такие как .svx
, если вы планируете использовать эти типы файлов).
svelte.config.js
export default {
preprocess: [
// your existing config
],
extensions: ['.svelte'], // Add this
kit: {
// your existing config...
}
};
Это вся конфигурация, которая нам нужна на данный момент. ☑️
Передача скомпилированной строки компоненту
Давайте настроим загрузчик маршрутов, который имитирует получение данных из API:
+page.server.ts
import type { Load } from '@sveltejs/kit';
const MOCK_RESPONSE_FROM_API = `
## Lorem
Lorem is currently extended with the following plugins.
Instructions on how to use them in your application are linked below.
| Plugin | README |
| ------ | ------ |
| Dropbox | [plugins/dropbox/README.md](Link) |
| Medium | [plugins/medium/README.md](Link) |
| Google Analytics | [plugins/googleanalytics/README.md](Link) |
`;
export const load: Load = async () => {
const response = MOCK_RESPONSE_FROM_API; // Get data with eg. `fetch`
return response;
};
Далее мы можем импортировать функцию compile
из mdsvex
, объявить переменную, передав в нее (mock) response
, и вернуть ее, чтобы она была доступна в нашем компоненте. Мы также занесем его в журнал, чтобы увидеть, что возвращается после compile
:
+page.server.ts
import { compile } from 'mdsvex';
// ...
const compiledResponse = await compile(response);
console.log('compiledResponse is: ', compiledResponse);
return compiledResponse;
// ...
вывод консоли (Учитывая, что это выполняется на стороне сервера, это можно увидеть в терминале, а не в консоли браузера)
Как вы можете видеть, Markdown был скомпилирован в то, что похоже на формат HTML-строки, добавленной вместе с оператором +
под ключом code
.
Поэтому мы можем обновить оператор возврата, включив в него только то, что нам нужно:
+page.server.ts
export const load: Load = async () => {
const res = MOCK_RESPONSE_FROM_API; // Get data with eg. `fetch`
const compiledResponse = await compile(res);
return { content: compiledResponse?.code };
};
Рендеринг HTML непосредственно в компоненте
Теперь из нашего компонента нам нужно только получить data
через export let
и отрендерить его.
Обычно строки вставляются как обычный текст, то есть такие символы, как < и > не имеют специального значения. Поэтому, учитывая, что у нас есть HTML, который мы хотим отобразить напрямую, мы можем использовать HTML-теги:
<p>{@html string}</p>
Так что в нашем случае…
+page.svelte
<script lang="ts">
export let data = {
content: ''
};
</script>
<div>{@html data.content}</div>
В результате мы получим отрендеренный Markdown 🪄:
Примечание из документации:
Svelte не проверяет выражения перед внедрением HTML. Если данные поступают из ненадежного источника, вы должны их санировать, иначе вы подвергаете своих пользователей XSS-уязвимости.
Дальнейшая настройка
Метод compile
принимает второй параметр, options
:
interface MdsvexOptions {
extensions: string[];
smartypants: boolean | smartypantsOptions;
layout: string | { [name: string]: string };
remarkPlugins: Array<plugin> | Array<[plugin, plugin_options]>;
rehypePlugins: Array<plugin> | Array<[plugin, plugin_options]>;
highlight: { highlighter: Function, alias: { [alias]: lang } };
frontmatter: { parse: Function; marker: string };
}
Это означает, что вы можете преобразовать ваш HTML с помощью таких инструментов, как rehype или remark. Вы можете узнать больше о доступных опциях здесь.
Вот и все! 👨💻
Если вам нужна дополнительная информация по вышеизложенному или чему-либо еще, связанному с этим — загляните в документацию SvelteKit, документацию MDX или в официальный дискорд Svelte.