A professional markdown viewer with file tree navigation, directory content browsing, and advanced YAML front matter support
npm install @asafarim/simple-md-viewertsx
// Example usage with custom package links
apiBaseUrl="http://localhost:3300"
packageLinks={{
packageName: "your-app-or-package-name",
githubPath: "your-github-repo",
demoPath: "https://your-live-demo-site.com",
show: true // Set to false to hide package links
}}
/>
`
π What's New in v1.5.0
$3
Professional directory content viewing with comprehensive file information:
- Multiple View Styles: Switch between list, grid, and detailed table views
- File Size Display: Real-time calculation and display of file and folder sizes
- Sorting & Filtering: Sort by name, type, size, or modification date with search filtering
- Responsive Design: Optimized layouts for desktop and mobile devices
- Breadcrumb Navigation: Easy navigation through directory hierarchies
- Loading States: Smooth loading indicators while fetching directory details
!Directory Views
Desktop directory view showing grid and detailed table layouts
!Mobile Directory View
Mobile-optimized directory view with touch-friendly interface
#### Directory View Features
- List View: Clean, compact file listing with icons
- Grid View: Visual grid layout with larger icons and file types
- Detailed View: Comprehensive table with file sizes, modification dates, and metadata
- Smart Sorting: Intelligent sorting with folders prioritized over files
- Real-time Search: Instant filtering of directory contents
- Size Calculation: Automatic calculation of folder sizes and file counts
π What's New in v1.4.0
$3
Professional YAML front matter parsing and display with comprehensive metadata support:
- Multiple Display Modes: Choose from full, minimal, header-only, or hidden display modes
- Rich Metadata Support: Title, description, author, dates, categories, tags, keywords, and more
- International Date Formatting: Built-in support for Belgian date formats (nl-BE, fr-BE)
- Navigation Integration: Automatic breadcrumbs and related page links from front matter
- Professional Styling: Clean, organized display with theme-aware styling
- GitHub Flavored Markdown: Enhanced table support and complete GFM compatibility
#### Example Front Matter
`yaml
---
title: "API Documentation"
description: "Complete API reference guide"
author: "Your Name"
lastModified: "2025-01-20"
locale: "nl-BE" # Belgian Dutch date formatting
category: "Documentation"
tags:
- api
- reference
breadcrumbs:
- name: "Home"
path: "/"
- name: "API"
path: "/api"
---
`
This will be beautifully rendered with proper styling, showing formatted dates, organized metadata, and navigation elements.
πͺ Live Demo
Experience the viewer in action: Live Demo
$3
Check out our Demo Repository for complete examples of how to integrate and use the Simple Markdown Viewer in your projects. This repository contains working examples with different configuration options and implementation patterns.
!Simple Markdown Viewer Demo
π¦ Installation
`bash
npm install @asafarim/simple-md-viewer
`
$3
The package requires CSS styles to be imported. Choose one of these methods:
`tsx
// Method 1: Import from dist (recommended)
import '@asafarim/simple-md-viewer/dist/style.css';
// Method 2: Alternative import path
import '@asafarim/simple-md-viewer/style.css';
`
$3
If you encounter TypeScript errors with CSS imports, add this to your project's type declarations:
`typescript
// In your global.d.ts or vite-env.d.ts
declare module '@asafarim/simple-md-viewer/dist/style.css';
declare module '@asafarim/simple-md-viewer/style.css';
`
π Quick Start
$3
The easiest way to get started - includes everything you need:
`tsx
import React, { useState, useEffect } from 'react';
import { HashRouter } from 'react-router-dom';
import { MarkdownContent, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function App() {
const [theme, setTheme] = useState(() => {
// Check localStorage for saved theme preference
const savedTheme = localStorage.getItem('smv-theme');
return savedTheme || 'light';
});
const toggleTheme = () => {
setTheme(prevTheme => {
const newTheme = prevTheme === 'light' ? 'dark' : 'light';
localStorage.setItem('smv-theme', newTheme);
return newTheme;
});
};
// Apply theme to document root for global styling
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
return (
app ${theme}}>
apiBaseUrl="http://localhost:3300"
showHomePage={true}
hideFileTree={false}
packageLinks={{
packageName: "@asafarim/simple-md-viewer",
githubPath: "simple-md-viewer",
demoPath: "https://alisafari-it.github.io/simple-md-viewer/#/README.md",
show: true
}}
/>
);
}
export default App;
`
$3
For more control, use individual components:
`tsx
import React, { useState, useEffect } from 'react';
import {
MarkdownViewer,
FileTree,
ThemeProvider
} from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function CustomApp() {
const [content, setContent] = useState('# Hello World\nYour markdown here...');
const [theme, setTheme] = useState(() => {
return localStorage.getItem('smv-theme') || 'light';
});
const toggleTheme = () => {
setTheme(prevTheme => {
const newTheme = prevTheme === 'light' ? 'dark' : 'light';
localStorage.setItem('smv-theme', newTheme);
return newTheme;
});
};
// Apply theme globally
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
return (
app ${theme}}>
);
}
`
$3
Perfect for embedded documentation, single-document viewing, or mobile-optimized reading:
`tsx
import React, { useState, useEffect } from 'react';
import { HashRouter } from 'react-router-dom';
import { MarkdownContent, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function FullWidthViewer() {
const [theme, setTheme] = useState('light');
return (
setTheme(theme === 'light' ? 'dark' : 'light')}>
apiBaseUrl="http://localhost:3300"
showHomePage={true}
hideFileTree={true} // π― This hides the file tree for full-width content
packageLinks={{
show: false // π― Hide package links for cleaner interface
}}
/>
);
}
`
Perfect for:
- π± Mobile-first applications - Maximum content space
- π― Single document focus - Remove navigation distractions
- π§ Embedded viewers - Integrate into existing dashboards
- π Blog post display - Clean, distraction-free reading
- πͺ Presentation mode - Full-screen document viewing
$3
Perfect for embedding in other applications with minimal UI chrome:
`tsx
import React from 'react';
import { HashRouter } from 'react-router-dom';
import { MarkdownContent, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function MinimalViewer() {
return (
apiBaseUrl="http://localhost:3300"
showHomePage={false}
hideFileTree={true} // π― Hide file tree for clean layout
hideHeader={true} // π― Hide header for minimal chrome
hideFooter={true} // π― Hide footer for clean integration
packageLinks={{
show: false // π― Hide package links (though header is already hidden)
}}
/>
);
}
`
Perfect for:
- π API documentation widgets - Embed docs in admin panels
- π± Mobile apps - Ultra-clean content display
- ποΈ Dashboard integration - Content without competing UI elements
- π Help systems - Context-sensitive documentation
- π― Content-only views - Maximum focus on the markdown content
π Usage Examples
Here are some common usage examples (also available in our Demo Repository): showcasing the advanced YAML front matter capabilities:
$3
`tsx
import React, { useState, useEffect } from 'react';
import { HashRouter } from 'react-router-dom';
import { MarkdownContent, MarkdownViewer, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function DocumentationSite() {
const [theme, setTheme] = useState('light');
// Complete setup with all front matter features enabled
return (
setTheme(theme === 'light' ? 'dark' : 'light')}>
app ${theme}}>
apiBaseUrl="http://localhost:3300"
showHomePage={true}
hideFileTree={false}
hideHeader={false}
hideFooter={false}
// Front matter is automatically handled by MarkdownViewer inside MarkdownContent
/>
);
}
`
$3
`tsx
import React from 'react';
import { MarkdownViewer, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function CustomDocumentViewer() {
const markdownWithFrontMatter = ---
;
return (
{/ Full front matter display - shows everything /}
content={markdownWithFrontMatter}
showFrontMatter={true}
frontMatterMode="full"
/>
);
}
`
$3
`tsx
// Minimal mode - shows only essential info
content={markdownWithFrontMatter}
showFrontMatter={true}
frontMatterMode="minimal" // Shows: author, date, version only
/>
// Header-only mode - shows title and description
content={markdownWithFrontMatter}
showFrontMatter={true}
frontMatterMode="header-only" // Shows: title, description only
/>
// Hidden mode - parses but doesn't display front matter
content={markdownWithFrontMatter}
showFrontMatter={false}
frontMatterMode="hidden" // Front matter parsed but not shown
/>
// Full mode (default) - shows all metadata in organized sections
content={markdownWithFrontMatter}
showFrontMatter={true}
frontMatterMode="full" // Shows: all metadata in sections
/>
`
$3
`tsx
const belgianContentNL = ---
;
const belgianContentFR = ---
;
// Dates will be formatted according to Belgian conventions
`
$3
`tsx
// Enable directory browsing with detailed view by default
apiBaseUrl="http://localhost:3300"
directoryViewEnabled={true}
directoryViewStyle="detailed" // Shows file sizes, dates, metadata
showDirectoryBreadcrumbs={true}
enableDirectorySorting={true}
/>
// Grid view for visual file browsing
apiBaseUrl="http://localhost:3300"
directoryViewStyle="grid" // Visual grid layout
showDirectoryBreadcrumbs={true}
enableDirectorySorting={true}
/>
// Minimal list view without breadcrumbs
apiBaseUrl="http://localhost:3300"
directoryViewStyle="list" // Clean, compact listing
showDirectoryBreadcrumbs={false}
enableDirectorySorting={false}
/>
// Disable directory view entirely (files only)
apiBaseUrl="http://localhost:3300"
directoryViewEnabled={false} // Directories won't show content
/>
`
Directory View Features Demonstrated:
- π File size calculation: Real-time size display for files and folders
- π
Modification dates: Last modified timestamps with localized formatting
- π Search and filtering: Instant search through directory contents
- π― Smart sorting: Sort by name, type, size, or date with folder prioritization
- π± Responsive layouts: Touch-friendly mobile interface with optimized views
- π§ Navigation: Breadcrumbs and related page links
`
Front Matter Features Demonstrated:
- π·οΈ Rich Metadata: Title, description, author, dates, version, categories, tags
- ποΈ Date Formatting: Automatic Belgian locale support (nl-BE, fr-BE)
- π§ Navigation: Breadcrumbs and related page links
- π Organization: Categories, sections, ordering, and table of contents flags
- π¨ Display Modes: Four modes from full metadata to hidden
- π SEO Support: Keywords and structured data for better discoverability
οΏ½ποΈ Backend Setup
Create a simple Express server to serve your markdown files:
`javascript
const express = require('express');
const fs = require('fs');
const path = require('path');
const cors = require('cors');
const app = express();
const PORT = 3300;
const mdDocsPath = path.join(__dirname, 'md-docs'); // Your markdown folder
app.use(cors({ origin: 'http://localhost:5173' }));
// API to return folder structure
app.get('/api/folder-structure', (req, res) => {
const folderStructure = getFolderStructure(mdDocsPath);
res.json({ nodes: folderStructure });
});
// API to serve markdown files
app.get('/api/file', (req, res) => {
const filePath = path.join(mdDocsPath, req.query.path);
if (fs.existsSync(filePath)) {
const content = fs.readFileSync(filePath, 'utf-8');
res.json({ content });
} else {
res.status(404).json({ error: 'File not found' });
}
});
// API to get directory details with file sizes (NEW in v1.5.0)
app.get('/api/directory-details', (req, res) => {
try {
const directoryPath = req.query.path || '';
const fullPath = path.join(mdDocsPath, directoryPath);
if (!fs.existsSync(fullPath) || !fs.statSync(fullPath).isDirectory()) {
return res.status(404).json({ error: 'Directory not found' });
}
const directoryDetails = getDirectoryDetails(fullPath, directoryPath);
res.json(directoryDetails);
} catch (error) {
res.status(500).json({ error: 'Failed to read directory details' });
}
});
function getFolderStructure(dirPath, relativePath = '') {
const items = fs.readdirSync(dirPath);
const result = [];
for (const item of items) {
const itemPath = path.join(dirPath, item);
const stats = fs.statSync(itemPath);
const itemRelativePath = path.join(relativePath, item).replace(/\\/g, '/');
if (stats.isDirectory()) {
result.push({
name: item,
path: itemRelativePath,
type: 'folder',
children: getFolderStructure(itemPath, itemRelativePath)
});
} else if (item.endsWith('.md')) {
result.push({
name: item,
path: itemRelativePath,
type: 'file'
});
}
}
return result;
}
// Helper functions for directory details (NEW in v1.5.0)
function getDirectoryDetails(dirPath, relativePath = '') {
const items = fs.readdirSync(dirPath);
const children = [];
for (const item of items) {
const itemPath = path.join(dirPath, item);
const stats = fs.statSync(itemPath);
const itemRelativePath = path.join(relativePath, item).replace(/\\/g, '/');
if (stats.isDirectory()) {
const folderSize = calculateFolderSize(itemPath);
const itemCount = countItemsInFolder(itemPath);
children.push({
name: item,
path: itemRelativePath,
type: 'folder',
size: folderSize,
lastModified: stats.mtime.toISOString(),
itemCount: itemCount
});
} else if (item.endsWith('.md')) {
children.push({
name: item,
path: itemRelativePath,
type: 'file',
size: stats.size,
lastModified: stats.mtime.toISOString(),
extension: path.extname(item).substring(1)
});
}
}
return {
name: path.basename(dirPath) || 'root',
path: relativePath,
type: 'folder',
children: children
};
}
function calculateFolderSize(folderPath) {
let totalSize = 0;
function traverse(currentPath) {
const items = fs.readdirSync(currentPath);
for (const item of items) {
const itemPath = path.join(currentPath, item);
const stats = fs.statSync(itemPath);
if (stats.isDirectory()) {
traverse(itemPath);
} else {
totalSize += stats.size;
}
}
}
traverse(folderPath);
return totalSize;
}
function countItemsInFolder(folderPath) {
let count = 0;
function traverse(currentPath) {
const items = fs.readdirSync(currentPath);
count += items.length;
for (const item of items) {
const itemPath = path.join(currentPath, item);
const stats = fs.statSync(itemPath);
if (stats.isDirectory()) {
traverse(itemPath);
}
}
}
traverse(folderPath);
return count;
}
app.listen(PORT, () => {
console.log(π Server running at http://localhost:${PORT});
});
`
π¨ Styling & Theming
$3
`tsx
import '@asafarim/simple-md-viewer/dist/style.css';
`
$3
Override CSS custom properties to customize the appearance:
`css
:root {
/ Light theme colors /
--bg-color-light: #ffffff;
--text-color-light: #333333;
--accent-primary-light: #2196f3;
--header-bg-light: #f8f9fa;
/ Dark theme colors /
--bg-color-dark: #1e1e1e;
--text-color-dark: #e0e0e0;
--accent-primary-dark: #64b5f6;
--header-bg-dark: #252526;
/ Typography /
--font-family-primary: 'Inter', -apple-system, sans-serif;
/ Spacing /
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
}
`
π API Reference
$3
#### MarkdownContent
The main component providing a complete markdown viewer experience.
`tsx
apiBaseUrl="http://localhost:3300"
showHomePage={true}
hideFileTree={false}
hideHeader={false}
hideFooter={false}
showFrontMatter={true}
frontMatterMode="full"
directoryViewEnabled={true}
directoryViewStyle="list"
showDirectoryBreadcrumbs={true}
enableDirectorySorting={true}
/>
`
Props:
- apiBaseUrl? (string): Base URL for API endpoints (default: "")
- showHomePage? (boolean): Whether to show homepage when no file is selected (default: true)
- hideFileTree? (boolean): Hide the file tree sidebar and expand content to full width (default: false)
- hideHeader? (boolean): Hide the header section including logo, theme toggle, and menu (default: false)
- hideFooter? (boolean): Hide the footer section for a more minimalistic view (default: false)
- showFrontMatter? (boolean): Whether to show YAML front matter in markdown files (default: true)
- frontMatterMode? ('full' | 'minimal' | 'header-only' | 'hidden'): How to display YAML front matter (default: 'full')
- directoryViewEnabled? (boolean): Enable directory content view when folders are selected (default: true)
- directoryViewStyle? ('list' | 'grid' | 'detailed'): Default view style for directory content (default: 'list')
- showDirectoryBreadcrumbs? (boolean): Show breadcrumbs navigation in directory view (default: true)
- enableDirectorySorting? (boolean): Enable sorting and filtering in directory view (default: true)
#### ThemeProvider
Provides theme context to all child components.
`tsx
setTheme('dark')}>
{children}
`
Props:
- theme ("light" | "dark"): Current theme
- toggleTheme? (function): Optional theme toggle function
- children (ReactNode): Child components
#### MarkdownViewer
Renders markdown content with syntax highlighting and YAML front matter support.
`tsx
content="# Hello World\nYour markdown content here..."
showFrontMatter={true}
frontMatterMode="full"
/>
`
Props:
- content (string): Markdown content to render (required)
- showFrontMatter? (boolean): Whether to display YAML front matter (default: true)
- frontMatterMode? ('full' | 'minimal' | 'header-only' | 'hidden'): Front matter display mode (default: 'full')
Front Matter Display Modes:
- 'full': Shows all front matter metadata in organized sections
- 'minimal': Shows only basic info (author, date, version)
- 'header-only': Shows only title and description
- 'hidden': Hides front matter display entirely
#### FileTree
Interactive file tree navigation component.
`tsx
fileTree={fileTreeData}
onFileSelect={(path) => handleFileSelect(path)}
selectedFile="/current/file.md"
/>
`
Props:
- fileTree (FileNode | null): File tree data structure
- onFileSelect (function): Callback when a file is selected
- selectedFile (string | null): Currently selected file path
#### DirectoryView
Advanced directory content browser with multiple view styles and file information.
`tsx
directory={directoryNode}
onFileSelect={(path) => handleFileSelect(path)}
onDirectorySelect={(path) => handleDirectorySelect(path)}
viewStyle="detailed"
showBreadcrumbs={true}
enableSorting={true}
enableFiltering={true}
loading={false}
/>
`
Props:
- directory (FileNode): Directory node with children to display (required)
- onFileSelect (function): Callback when a file is selected (required)
- onDirectorySelect? (function): Callback when a directory is selected
- viewStyle? ('list' | 'grid' | 'detailed'): View style for displaying directory contents (default: 'list')
- showBreadcrumbs? (boolean): Show breadcrumb navigation (default: true)
- enableSorting? (boolean): Enable sorting controls (default: true)
- enableFiltering? (boolean): Enable search filtering (default: true)
- loading? (boolean): Show loading state (default: false)
- className? (string): Additional CSS classes
View Styles:
- 'list': Compact list view with file icons and names
- 'grid': Grid layout with larger icons and file type labels
- 'detailed': Table view with file sizes, modification dates, and comprehensive metadata
#### HomePage
Landing page component showing available documentation.
`tsx
fileTree={fileTreeData}
findReadmeNode={findReadmeFunction}
loading={false}
/>
`
Props:
- fileTree (FileNode | null): File tree data
- findReadmeNode (function): Function to find README file
- loading (boolean): Loading state
#### FrontMatterDisplay
Displays parsed YAML front matter with professional styling.
`tsx
frontMatter={parsedFrontMatter}
mode="full"
/>
`
Props:
- frontMatter (FrontMatter): Parsed front matter object (required)
- mode? ('full' | 'minimal' | 'header-only'): Display mode (default: 'full')
Example Usage:
`tsx
import { parseFrontMatter, FrontMatterDisplay } from '@asafarim/simple-md-viewer';
const markdownWithFrontMatter = ---
;
const { frontMatter, content } = parseFrontMatter(markdownWithFrontMatter);
`
$3
#### FileNode
`typescript
interface FileNode {
name: string;
path: string;
type: 'file' | 'folder';
children?: FileNode[];
}
`
#### ThemeContextType
`typescript
interface ThemeContextType {
theme: 'light' | 'dark';
toggleTheme?: () => void;
}
`
#### FrontMatter
`typescript
interface FrontMatter {
title?: string;
description?: string;
author?: string;
date?: string;
lastModified?: string;
version?: string;
category?: string;
section?: string;
order?: number;
tags?: string[];
keywords?: string[];
toc?: boolean;
sidebar?: boolean;
locale?: string; // Date formatting locale (e.g., 'en-US', 'nl-BE', 'fr-BE')
breadcrumbs?: Array<{
name: string;
path: string;
}>;
related?: Array<{
title: string;
path: string;
}>;
[key: string]: any; // Allow additional custom properties
}
`
#### ParsedMarkdown
`typescript
interface ParsedMarkdown {
frontMatter: FrontMatter | null;
content: string;
}
`
π§ Complete Project Setup
$3
`bash
mkdir my-docs-site
cd my-docs-site
npm init -y
`
$3
`bash
npm install @asafarim/simple-md-viewer react react-dom react-router-dom
npm install --save-dev vite @vitejs/plugin-react typescript
npm install express cors concurrently
`
$3
`
my-docs-site/
βββ package.json
βββ vite.config.ts
βββ server.js
βββ src/
β βββ main.tsx
β βββ App.tsx
β βββ vite-env.d.ts
βββ public/
β βββ index.html
βββ md-docs/ # Your markdown files
βββ README.md
βββ getting-started.md
βββ api/
βββ reference.md
`
$3
`typescript
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 5173,
},
});
`
$3
`json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "node server.js",
"start": "concurrently \"npm run dev\" \"npm run serve\""
}
}
`
$3
`tsx
// src/App.tsx
import React, { useState, useEffect } from 'react';
import { HashRouter } from 'react-router-dom';
import { MarkdownContent, ThemeProvider } from '@asafarim/simple-md-viewer';
import '@asafarim/simple-md-viewer/dist/style.css';
function App() {
const [theme, setTheme] = useState(() => {
return localStorage.getItem('smv-theme') || 'light';
});
const toggleTheme = () => {
setTheme(prevTheme => {
const newTheme = prevTheme === 'light' ? 'dark' : 'light';
localStorage.setItem('smv-theme', newTheme);
return newTheme;
});
};
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
return (
app ${theme}}>
apiBaseUrl="http://localhost:3300"
showHomePage={true}
/>
);
}
export default App;
`
`tsx
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
);
`
$3
`bash
npm start
`
Your documentation site will be available at http://localhost:5173
π± Mobile Responsiveness
The viewer is fully responsive with:
- Mobile (< 768px): Collapsible sidebar overlay with touch-friendly navigation
- Tablet (768px - 1024px): Optimized layout with compressed sidebar
- Desktop (> 1024px): Full sidebar and content layout
$3
- Touch-friendly navigation
- Collapsible sidebar with backdrop overlay
- Optimized typography scaling
- Gesture-friendly interface elements
- Proper viewport handling
π― Use Cases
$3
Perfect for API documentation, user guides, and technical specifications.
$3
Organize team processes, onboarding materials, and internal documentation.
$3
Create a clean, navigable blog or article collection.
$3
Build course materials, tutorials, and learning resources.
$3
Document project requirements, architecture, and technical specifications.
$3
When you want to display markdown content without file navigation, perfect for:
#### Single Document Viewer
`tsx
showHomePage={false}
apiBaseUrl="http://localhost:3300"
hideFileTree={true}
/>
`
- Blog post viewer: Display a single article without navigation clutter
- Embedded documentation: Integrate into existing dashboards or applications
- Mobile-optimized reading: Maximize content space on small screens
- Presentation mode: Full-width display for presentations or demos
$3
For ultra-clean integration into existing applications:
#### Embedded Widget Mode
`tsx
showHomePage={false}
apiBaseUrl="/api/docs"
hideFileTree={true}
hideHeader={true}
hideFooter={true}
/>
`
- API documentation widgets: Clean docs in admin panels
- Help system integration: Context-sensitive help without UI conflicts
- Mobile app embedding: Ultra-minimal chrome for mobile apps
- Dashboard content: Documentation that blends with existing UI
- White-label solutions: Remove branding for third-party integrations
- Mobile-optimized reading: Maximize content space on small screens
- Presentation mode: Full-width display for presentations or demos
#### Content-First Applications
`tsx
// Perfect for applications where content is king
function DocumentReader() {
return (
showHomePage={true}
apiBaseUrl="/api/docs"
hideFileTree={true}
/>
);
}
`
#### When to Use hideFileTree={true}:
- β
Single document focus: When users should focus on one piece of content
- β
Embedded viewers: Integrating into existing applications with their own navigation
- β
Mobile-first experience: Maximizing content space on smaller screens
- β
Clean presentation: When file tree navigation would be distracting
- β
Dashboard integration: Embedding docs into admin panels or dashboards
π§ Advanced Configuration
$3
`env
.env
VITE_API_BASE_URL=http://localhost:3300
VITE_DEFAULT_THEME=light
`
$3
The viewer includes built-in support for package links:
`tsx
import { CollapsiblePackageLinks } from '@asafarim/simple-md-viewer';
packageName="@asafarim/simple-md-viewer"
githubPath="AliSafari-IT/simple-md-viewer"
demoPath="https://alisafari-it.github.io/simple-md-viewer/"
/>
`
$3
`tsx
import { ThemeProvider } from '@asafarim/simple-md-viewer';
function App() {
const [theme, setTheme] = useState(() => {
// Check localStorage and system preference
const savedTheme = localStorage.getItem('smv-theme');
if (savedTheme) return savedTheme;
// Check system preference
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
});
const toggleTheme = () => {
setTheme(prevTheme => {
const newTheme = prevTheme === 'light' ? 'dark' : 'light';
localStorage.setItem('smv-theme', newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
return newTheme;
});
};
// Listen for system theme changes
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e) => {
if (!localStorage.getItem('smv-theme')) {
setTheme(e.matches ? 'dark' : 'light');
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
return (
{/ Your app content /}
);
}
`
$3
Here are common configuration patterns for different use cases:
#### Full-Featured Documentation Site
`tsx
apiBaseUrl="http://localhost:3300"
showHomePage={true}
hideFileTree={false}
hideHeader={false}
hideFooter={false}
/>
`
#### Mobile-Optimized Content Viewer
`tsx
apiBaseUrl="/api/docs"
showHomePage={true}
hideFileTree={true} // Maximize content space
hideHeader={false} // Keep theme toggle and branding
hideFooter={true} // Remove footer for more space
/>
`
#### Embedded Widget (Minimal Chrome)
`tsx
apiBaseUrl="/api/help"
showHomePage={false} // Direct to content
hideFileTree={true} // No navigation needed
hideHeader={true} // Remove all chrome
hideFooter={true} // Ultra-clean integration
/>
`
#### Dashboard Documentation Panel
`tsx
apiBaseUrl="/api/docs"
showHomePage={false}
hideFileTree={true} // Clean layout
hideHeader={true} // Integrate with dashboard header
hideFooter={false} // Keep footer for branding
/>
`
#### Blog Post Reader
`tsx
apiBaseUrl="/api/blog"
showHomePage={true}
hideFileTree={true} // Focus on content
hideHeader={false} // Keep navigation
hideFooter={false} // Keep branding
/>
`
π Deployment
$3
`bash
Build your project
npm run build
Deploy to GitHub Pages
npm run deploy
`
$3
Simply connect your repository and deploy the dist folder.
$3
`dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 5173
CMD ["npm", "start"]
`
π οΈ Development
$3
`bash
git clone https://github.com/AliSafari-IT/simple-md-viewer.git
cd simple-md-viewer
npm install
npm start
`
$3
`bash
npm run build:lib # Build library for npm
npm run build # Build demo application
`
π€ Contributing
We welcome contributions! Please see our Contributing Guide.
$3
1. Fork the repository
2. Create your feature branch: git checkout -b feature/amazing-feature
3. Commit your changes: git commit -m 'Add amazing feature'
4. Push to the branch: git push origin feature/amazing-feature`