# How to add RemarkJS to a Jekyll blog * What is [RemarkJS - Markdown-driven Slideshow Tool](https://remarkjs.com/)? * Why combine it with [Jekyll - Static Site Generator](https://jekyllrb.com/)? * Step-by-step implementation * Real-world examples from this blog * Advanced customization * Best practices and tips --- ## What is RemarkJS? [RemarkJS - Markdown-driven Slideshow Tool](https://remarkjs.com/) is a simple, in-browser, markdown-driven slideshow tool. ### Key Features: * **Markdown-based** - Write slides in familiar Markdown syntax * **Browser-native** - No external dependencies or build tools * **Keyboard navigation** - Arrow keys, page up/down, and more * **Presenter mode** - Dual-screen support with notes * **Themeable** - Customise with CSS * **Lightweight** - Single JavaScript file (~85KB) ### Why RemarkJS? * Simple syntax for complex presentations * Version control friendly (plain text) * Easy to integrate with static site generators * Perfect for technical presentations with code --- ## Why Jekyll + RemarkJS? ### The Perfect Combination **[Jekyll - Static Site Generator](https://jekyllrb.com/) provides:** * Static site generation * Template system with Liquid * Markdown processing * [GitHub Pages Documentation](https://pages.github.com/) hosting **RemarkJS adds:** * Interactive presentations * Browser-based slideshow capabilities * Professional presentation features --- ## Benefits * **One codebase** - Blog posts and presentations in the same repository * **Consistent styling** - Shared CSS and theme * **Easy deployment** - Automatic publishing via GitHub Pages * **SEO friendly** - Each presentation gets its own URL * **Reusable content** - Include presentation content in blog posts --- ## Architecture Overview ### This Blog's Setup ``` ├── _layouts/ │ └── presentation.html # RemarkJS presentation layout ├── _includes/ │ └── presentations/ # Presentation content files │ ├── 001-spring-boot.md │ ├── 002-testing.md │ └── ... ├── _posts/ │ └── 2024-01-01-my-talk.md # Presentation wrapper posts ├── assets/ │ ├── css/ │ │ └── custom-remark.css # Custom RemarkJS styling │ └── js/ │ └── remark-0.14.1.min.js # RemarkJS library └── presentations.html # Presentations index page ``` ### Data Flow: 1. **Content** → `_includes/presentations/talk.md` 2. **Post** → `_posts/2024-talk.md` (includes content) 3. **Layout** → `_layouts/presentation.html` (RemarkJS setup) 4. **Styling** → `assets/css/custom-remark.css` --- ## Download RemarkJS to your project ### Get the Library ```bash # Download RemarkJS to your assets directory curl -o assets/js/remark-latest.min.js https://remarkjs.com/downloads/remark-latest.min.js # Or use a specific version (recommended) curl -o assets/js/remark-0.14.1.min.js \ https://github.com/gnab/remark/releases/download/v0.14.0/remark.min.js ``` ### File Structure ``` assets/ └── js/ └── remark-0.14.1.min.js # 85KB minified ``` **Why local hosting?** * Reliable access (no CDN dependencies) * Consistent performance * Works offline during development --- ## Create Presentation Layout and Styling - Create a custom layout that will be used when rendering presentations. - Checkout this file for a custom layout in Jekyll `_layouts/presentation.html` - Create custom styling to be applied for presentations. - The content of this file should help `assets/css/custom-remark.css` - All presentations live in `_includes/presentations` - Each presentation lives in the `presentations` directory - Create a presentation slide and add your content: `_includes/presentations/my-talk.md` --- ## Create Presentation Post ### Post Content Post title is `_posts/2024-01-15-my-amazing-talk.md` Post content is only the import of the presentation file: --- layout: presentation title: My Amazing Talk permalink: /presentations/my-amazing-talk/ tags: [presentation, demo, tutorial] description: A comprehensive guide to building amazing presentations --- <pre>{% include presentations/my-talk.md %}</pre> ### Key Elements: * **`layout: presentation`** - Uses our custom layout * **`permalink:`** - Clean URL structure * **`` tag** - Preserves formatting for RemarkJS * **`{% include %}`** - Separates content from metadata --- ## Code Highlighting - With a RemarkJS Extension RemarkJS supports syntax highlight with some built-in extensions. ### Basic Code Blocks: ```java public class Example { public void method() { System.out.println("Hello"); } } ``` --- ## Images and Media ### Responsive Images: Markdown: `` HTML with custom image sizing: `` ### Background Images: background-image: url(path/to/background.jpg) # Slide Title Content with background image --- ## Integration with Jekyll ### Using Jekyll Variables: # Welcome to {{ site.title }} Today: {{ site.time | date: "%B %d, %Y" }} Presenter: {{ page.author | default: "George Racu" }} ### Including Shared Content: # About the Speaker {% include speaker-bio.md %} # Contact Information {% include contact-info.md %} ### Liquid Filters: # Recent Posts {% for post in site.posts limit:3 %} * [{{ post.title }}]({{ post.url }}) {% endfor %} --- ## Performance Optimisation ### Loading Speed: * **Use local RemarkJS** - No CDN delays * **Optimize images** - Compress presentation images * **Minimize CSS** - Remove unused styles * **Lazy loading** - Load slides on demand ### Browser Performance: ```javascript // In presentation.html var slideshow = remark.create({ slideNumberFormat: '', // Disable slide numbers for performance ratio: '16:9', // Set aspect ratio navigation: { scroll: false, // Disable scroll for mobile performance touch: true, // Enable touch for mobile click: false // Prevent accidental clicks } }); ``` --- ## Mobile Optimisation ```css /* Responsive design */ @media (max-width: 768px) { .remark-slide-content { font-size: 1.2em; padding: 1em; } .remark-code { font-size: 0.9em; } } ``` --- ## Best Practices ### Content Organization: * **One concept per slide** - Keep it simple * **Use bullet points** - Easy to scan * **Limit text** - More visuals, less text * **Consistent formatting** - Use templates ### File Management: * **Separate content files** - Keep in `_includes/presentations/` * **Descriptive filenames** - `001-topic-name.md` * **Version control** - Git-friendly plain text * **Reusable components** - Common headers/footers ### Presentation Tips: * **Test on target devices** - Different screens/browsers * **Prepare for offline** - Local assets * **Practice navigation** - Know your shortcuts * **Have backups** - PDF export, local copies --- ## Troubleshooting ### Common Issues: **Slides not loading:** Check textarea id **Formatting problems:** Ensure proper slide separators: `---` Not `--` or `----` **JavaScript errors:** ```html ``` **Mobile issues:** ```css /* Add viewport meta tag */ ``` --- ## Real Examples from This Blog ### File Structure: ```plain _includes/presentations/ ├── 001-spring-boot-on-k8s.md # Kubernetes deployment ├── 002-code-fit-for-testing.md # Testing practices ├── 003-curse-of-optional.md # Java Optional guide ├── 004-efficient-java.md # Immutability patterns └── 2021-09-01-remarkjs-jekyll.md # This presentation! ``` ### Generated URLs: * `/presentations/run-spring-boot-on-kubernetes/` * `/presentations/write-code-fit-for-testing/` * `/presentations/curse-of-optional/` * `/presentations/efficient-java/` ### Navigation Integration: ```html
--- layout: presentation title: My Amazing Talk permalink: /presentations/my-amazing-talk/ tags: [presentation, demo, tutorial] description: A comprehensive guide to building amazing presentations --- <pre>{% include presentations/my-talk.md %}</pre>
` tag** - Preserves formatting for RemarkJS * **`{% include %}`** - Separates content from metadata --- ## Code Highlighting - With a RemarkJS Extension RemarkJS supports syntax highlight with some built-in extensions. ### Basic Code Blocks: ```java public class Example { public void method() { System.out.println("Hello"); } } ``` --- ## Images and Media ### Responsive Images: Markdown: `` HTML with custom image sizing: `` ### Background Images: background-image: url(path/to/background.jpg) # Slide Title Content with background image --- ## Integration with Jekyll ### Using Jekyll Variables: # Welcome to {{ site.title }} Today: {{ site.time | date: "%B %d, %Y" }} Presenter: {{ page.author | default: "George Racu" }} ### Including Shared Content: # About the Speaker {% include speaker-bio.md %} # Contact Information {% include contact-info.md %} ### Liquid Filters: # Recent Posts {% for post in site.posts limit:3 %} * [{{ post.title }}]({{ post.url }}) {% endfor %} --- ## Performance Optimisation ### Loading Speed: * **Use local RemarkJS** - No CDN delays * **Optimize images** - Compress presentation images * **Minimize CSS** - Remove unused styles * **Lazy loading** - Load slides on demand ### Browser Performance: ```javascript // In presentation.html var slideshow = remark.create({ slideNumberFormat: '', // Disable slide numbers for performance ratio: '16:9', // Set aspect ratio navigation: { scroll: false, // Disable scroll for mobile performance touch: true, // Enable touch for mobile click: false // Prevent accidental clicks } }); ``` --- ## Mobile Optimisation ```css /* Responsive design */ @media (max-width: 768px) { .remark-slide-content { font-size: 1.2em; padding: 1em; } .remark-code { font-size: 0.9em; } } ``` --- ## Best Practices ### Content Organization: * **One concept per slide** - Keep it simple * **Use bullet points** - Easy to scan * **Limit text** - More visuals, less text * **Consistent formatting** - Use templates ### File Management: * **Separate content files** - Keep in `_includes/presentations/` * **Descriptive filenames** - `001-topic-name.md` * **Version control** - Git-friendly plain text * **Reusable components** - Common headers/footers ### Presentation Tips: * **Test on target devices** - Different screens/browsers * **Prepare for offline** - Local assets * **Practice navigation** - Know your shortcuts * **Have backups** - PDF export, local copies --- ## Troubleshooting ### Common Issues: **Slides not loading:** Check textarea id **Formatting problems:** Ensure proper slide separators: `---` Not `--` or `----` **JavaScript errors:** ```html ``` **Mobile issues:** ```css /* Add viewport meta tag */ ``` --- ## Real Examples from This Blog ### File Structure: ```plain _includes/presentations/ ├── 001-spring-boot-on-k8s.md # Kubernetes deployment ├── 002-code-fit-for-testing.md # Testing practices ├── 003-curse-of-optional.md # Java Optional guide ├── 004-efficient-java.md # Immutability patterns └── 2021-09-01-remarkjs-jekyll.md # This presentation! ``` ### Generated URLs: * `/presentations/run-spring-boot-on-kubernetes/` * `/presentations/write-code-fit-for-testing/` * `/presentations/curse-of-optional/` * `/presentations/efficient-java/` ### Navigation Integration: ```html
background-image: url(path/to/background.jpg) # Slide Title Content with background image
# Welcome to {{ site.title }} Today: {{ site.time | date: "%B %d, %Y" }} Presenter: {{ page.author | default: "George Racu" }}
# About the Speaker {% include speaker-bio.md %} # Contact Information {% include contact-info.md %}
# Recent Posts {% for post in site.posts limit:3 %} * [{{ post.title }}]({{ post.url }}) {% endfor %}