I created a templates/index.html that looks like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Your app description here">
<meta name="keywords" content="keyword1, keyword2, keyword3">
<title>{%title%}</title>
{%favicon%}
{%css%}
{%metas%}
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://yourwebsite.com/">
<meta property="og:title" content="Your App Title">
<meta property="og:description" content="Your app description here">
<meta property="og:image" content="https://yourwebsite.com/path/to/image.jpg">
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://yourwebsite.com/">
<meta property="twitter:title" content="Your App Title">
<meta property="twitter:description" content="Your app description here">
<meta property="twitter:image" content="https://yourwebsite.com/path/to/image.jpg">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-6WYY9JHMP2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-6WYY9JHMP2');
</script>
<!-- Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "Your App Name",
"description": "Your app description here",
"url": "https://yourwebsite.com",
"applicationCategory": "Your App Category",
"operatingSystem": "Web"
}
</script>
</head>
<body>
<main>
{%app_entry%}
</main>
<footer>
{%config%}
{%scripts%}
{%renderer%}
<p>© 2024 Your Company Name. All rights reserved.</p>
</footer>
</body>
</html>
and this has worked well for my project. I’ve built on top of dmc docs which is a genius code base imo, but it turns .md into pages with a markdown.py of:
import logging
from pathlib import Path
from typing import Optional
import dash
import dash_mantine_components as dmc
import frontmatter
from markdown2dash import Admonition, BlockExec, Divider, Image, create_parser
from pydantic import BaseModel
from lib.constants import PAGE_TITLE_PREFIX
from lib.directives.kwargs import Kwargs
from lib.directives.source import SC
from lib.directives.toc import TOC
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
directory = "docs"
# read all markdown files
files = Path(directory).glob("**/*.md")
class Meta(BaseModel):
name: str
description: str
endpoint: str
package: str = "dash_pydantic_form"
category: Optional[str] = None
icon: Optional[str] = None
def make_endpoint(name):
return "-".join(name.lower().split())
directives = [Admonition(), BlockExec(), Divider(), Image(), Kwargs(), SC(), TOC()]
parse = create_parser(directives)
for file in files:
logger.info("Loading %s..", file)
metadata, content = frontmatter.parse(file.read_text())
metadata = Meta(**metadata)
logger.info("Type of content: %s", type(content))
layout = parse(content)
# add heading and description to the layout
section = [
dmc.Title(metadata.name, order=2, className="m2d-heading"),
dmc.Text(metadata.description, className="m2d-paragraph"),
]
layout = section + layout
# register with dash
dash.register_page(
metadata.name,
metadata.endpoint,
name=metadata.name,
title=PAGE_TITLE_PREFIX + metadata.name,
description=metadata.description,
layout=layout,
category=metadata.category,
icon=metadata.icon,
)
so when I create new folders in the docs/folder/____.md I structure it like so:
---
name: Full Calendar
description: Use Full Calendar Component to create a dash calendar.
endpoint: /pip/full_calendar_component
package: full_calendar_component
icon: line-md:calendar
---
and the markdown.py will do all the magic of setting up the description for each page, creating the url and changing the title name which translates directly into better SEO if you look up individual pages on google.