{"id":23407699,"url":"https://github.com/bestia-dev/markdown_to_html","last_synced_at":"2025-07-23T00:03:53.815Z","repository":{"id":209189572,"uuid":"723422023","full_name":"bestia-dev/markdown_to_html","owner":"bestia-dev","description":"Render markdown to html client-side in the browser with WASM.","archived":false,"fork":false,"pushed_at":"2025-04-01T11:45:49.000Z","size":96,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T00:49:17.101Z","etag":null,"topics":["maintained","ready-for-use","tutorial"],"latest_commit_sha":null,"homepage":"https://bestia.dev/markdown_to_html_example","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bestia-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-25T16:07:35.000Z","updated_at":"2025-04-01T11:45:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"5edd5ce3-cf25-4024-8f0f-aee3210faacf","html_url":"https://github.com/bestia-dev/markdown_to_html","commit_stats":null,"previous_names":["bestia-dev/markdown_to_html"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bestia-dev/markdown_to_html","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestia-dev%2Fmarkdown_to_html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestia-dev%2Fmarkdown_to_html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestia-dev%2Fmarkdown_to_html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestia-dev%2Fmarkdown_to_html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bestia-dev","download_url":"https://codeload.github.com/bestia-dev/markdown_to_html/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestia-dev%2Fmarkdown_to_html/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266592120,"owners_count":23953106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["maintained","ready-for-use","tutorial"],"created_at":"2024-12-22T14:29:35.316Z","updated_at":"2025-07-23T00:03:53.779Z","avatar_url":"https://github.com/bestia-dev.png","language":"CSS","readme":"\u003c!-- markdownlint-disable MD041 --\u003e\n[//]: # (auto_md_to_doc_comments segment start A)\n\n# markdown_to_html\n\n[//]: # (auto_cargo_toml_to_md start)\n\n**Render markdown to html client-side in the browser with WASM.**  \n***version: 2023 date: 2023-11-17 author: [bestia.dev](https://bestia.dev) repository: [GitHub](https://github.com/bestia-dev/markdown_to_html)***  \n\n[//]: # (auto_cargo_toml_to_md end)\n\n ![maintained](https://img.shields.io/badge/maintained-green)\n ![ready_for_use](https://img.shields.io/badge/ready_for_use-green)\n ![tutorial](https://img.shields.io/badge/tutorial-yellow)\n ![License](https://img.shields.io/badge/license-MIT-blue.svg)\n ![markdown_to_html](https://bestia.dev/webpage_hit_counter/get_svg_image/2011538401.svg)\n\nHashtags: #tutorial #markdown #wasm  \nMy projects on GitHub are more like a tutorial than a finished product: [bestia-dev tutorials](https://github.com/bestia-dev/tutorials_rust_wasm).\n\n## Try it\n\n\u003chttps://bestia.dev/markdown_to_html_example\u003e\n\n## Markdown\n\nMarkdown is great! It is as easy as plain text but renders in a beautiful style that I could never achieve on my own in some Rich text or HTML.  \nThe syntax is super easy and it is human readable in both plain text and HTML format. \u003chttps://www.markdownguide.org/basic-syntax/\u003e  \nIn VSCode and many other editors, I can write Markdown files, and insert images and links. Then there is a Preview panel to watch how it renders.\n\nUsually, the markdown syntax is rendered to HTML. Many libraries do that.  \nI chose \u003chttps://github.com/rsms/markdown-wasm\u003e because it can be used inside a browser on the client side.  \n\n## Publish to Web\n\nNow I want to publish these markdown files to the Web. I have a small web server. I copy all the files there.  \nNo luck! Web browsers don't recognize and render markdown, just HTML.  \n\nI could use a server-side filter for Nginx or write my own Rust web app, but that is overkill.  \nI find it attractive to use Wasm in the browser to render the .md files on the fly.  \nI found this library: \u003chttps://github.com/rsms/markdown-wasm\u003e written in Rust and compiled to wasm.  \nWith some glue files and JavaScript, it is easy to make it work.\n\n## Files on the Web server\n\nFor this to work I need a simple Web server that returns files, nothing more. No dynamic web app or anything exotic.  \nIt will not work without a Web server on the local disk, because `wasm` files must be fetched from a Web server because of security.  \nLet's start with `index.html`. It will just redirect to the HTML file with JavaScript, adding the first_page.md file as a parameter.\n\n```HTML\n\u003cscript\u003e\nwindow.location.replace(\"mdtohtml.html?first_page.md\");\n\u003c/script\u003e\n```\n\nThe javascript program is all in the `mdtohtml.html`. There is some simple code to accept a URL parameter.  \nI also regex replaced the links inside the markdown to work with the new indirection.  \nFor simplicity I don't bother with subfolders. All .md files must be in the same folder.  \nAnd then we call the `markdown.parse()` method from the wasm module.  \n\u003chttps://github.com/rsms/markdown-wasm\u003e  \nSure we have to add some beautiful CSS that is similar to GitHub markdown.  \n\u003chttps://github.com/sindresorhus/github-markdown-css\u003e  \n\n```HTML\n\u003c!doctype html\u003e\n\u003chtml lang=\"en-US\"\u003e\n\u003chead\u003e\n    \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n    \u003clink rel=\"stylesheet\" href=\"github-markdown.css\"\u003e\n    \u003cscript src=\"markdown.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e\n        async function fetch_md_convert_to_html() {\n            let params = window.location.search;\n            if (params==''){\n                params = \"?first_page.md\";\n                window.location.search=params;\n            }\n            let mdFile = params.substring(1);\n            const response = await fetch(mdFile);\n            let mdText = await response.text();\n            mdText = mdText.replaceAll(/(\\[.*\\]\\()(.*\\.md\\))/g, '$1mdtohtml.html?$2'); \n            document.body.innerHTML=markdown.parse(mdText);\n        }\n    \u003c/script\u003e\n    \u003cstyle\u003e\n        .markdown-body {\n            box-sizing: border-box;\n            min-width: 200px;\n            max-width: 980px;\n            margin: 0 auto;\n            padding: 45px;\n        }\n        @media (max-width: 767px) {\n            .markdown-body {\n                padding: 15px;\n            }\n        }\n    \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody class=\"markdown-body\"\u003e\n    \u003cscript\u003e\n        fetch_md_convert_to_html();\n    \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e \n```\n\nWe need to add the magic ingredients to the folder: `markdown.js`, `markdown.wasm`, `github-markdown.css`\n\nand voila! It works.\n\n## Open-source and free as a beer\n\nMy open-source projects are free as a beer (MIT license).  \nI just love programming.  \nBut I need also to drink. If you find my projects and tutorials helpful, please buy me a beer by donating to my [PayPal](https://paypal.me/LucianoBestia).  \nYou know the price of a beer in your local bar ;-)  \nSo I can drink a free beer for your health :-)  \n[Na zdravje!](https://translate.google.com/?hl=en\u0026sl=sl\u0026tl=en\u0026text=Na%20zdravje\u0026op=translate) [Alla salute!](https://dictionary.cambridge.org/dictionary/italian-english/alla-salute) [Prost!](https://dictionary.cambridge.org/dictionary/german-english/prost) [Nazdravlje!](https://matadornetwork.com/nights/how-to-say-cheers-in-50-languages/) 🍻\n\n[//bestia.dev](https://bestia.dev)  \n[//github.com/bestia-dev](https://github.com/bestia-dev)  \n[//bestiadev.substack.com](https://bestiadev.substack.com)  \n[//youtube.com/@bestia-dev-tutorials](https://youtube.com/@bestia-dev-tutorials)  \n\n[//]: # (auto_md_to_doc_comments segment end A)\n","funding_links":["https://paypal.me/LucianoBestia"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestia-dev%2Fmarkdown_to_html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbestia-dev%2Fmarkdown_to_html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestia-dev%2Fmarkdown_to_html/lists"}