Skip to content

Commit 41aafcf

Browse files
authored
feat(website): comprehensive SEO overhaul and blog scaffold (#1340)
* feat: support binary WebSocket frames in message handlers Closes #1332 Propagate binary WebSocket frames (opcode 0x2) through the entire Rust→Python pipeline instead of silently echoing them back. - Add WsPayload enum (Text/Binary) to replace String throughout the WebSocket channel, registry messages, and send methods - Forward ws::Message::Binary through the channel so Python handlers receive bytes for binary frames and str for text frames - Accept str|bytes in send/broadcast methods, emitting the correct frame type on the wire - Add receive() returning str|bytes, fix receive_text/receive_bytes to validate frame type Made-with: Cursor * fix: harden WebSocket API safety and update type stubs - Replace UUID unwrap() with proper error handling in sync_send_to and async_send_to, returning PyValueError instead of panicking - Update robyn.pyi type stubs to accept str | bytes for send/broadcast methods, matching the Rust implementations - Add warning log in extract_ws_return for unsupported handler return types to aid debugging Made-with: Cursor * fix: add Python 3.14 to linux-cross matrix and bump maturin - Add cp314-cp314 entry to the linux-cross build matrix - Bump pinned maturin from v1.12.0 to v1.12.6 to support Python 3.14's build-details.json format (missing extension_suffix field) Made-with: Cursor * docs: update WebSocket docs for binary frame support - Document new receive() and send() methods for mixed text/binary frames - Add binary and mixed-frame code examples to both EN and ZH docs - Update API reference tables with receive(), send(), and updated descriptions for receive_text/bytes, send_bytes, and broadcast - Note that receive_text/receive_bytes now raise TypeError on wrong frame type Made-with: Cursor * feat(website): comprehensive SEO overhaul and blog scaffold Addresses critical SEO gaps across the Robyn website: - Add robots.txt and auto-generated sitemap via next-sitemap - Create reusable SEO component with canonical URLs, hreflang (en/zh), Open Graph, Twitter Cards, and JSON-LD structured data - Fix placeholder @yourTwitterHandle → @robaborobyn - Add per-page meta tags to community, releases, and docs pages - Add JSON-LD schemas: WebSite, SoftwareSourceCode, Organization, BreadcrumbList, TechArticle - Fix hardcoded lang="en" → dynamic locale from Next.js - Fix empty alt attributes on logo, testimonial photos, release images - Replace raw <a> tags with Next.js <Link> for internal navigation - Fix heading hierarchy (community h2→h1) - Fix "wor oad" typo in testimonial - Add custom 404 page - Add site.webmanifest with proper icon declarations - Scaffold blog section with index, [slug] dynamic routes, and sample welcome post - Add Blog link to header and footer navigation - Rename package.json from template name to robyn-website Made-with: Cursor * fix: address PR review findings across website and websocket code Website/SEO fixes: - Fix hreflang duplication: use router.locales/defaultLocale and strip locale prefix from path before building alternates - Escape JSON-LD output to prevent script-breakout via frontmatter - Remove references to non-existent favicon PNGs, use existing robynog.png - Add aria-current="page" to active breadcrumb item in blog posts - Guard getStaticProps/getBlogPostBySlug against missing files (return notFound: true) - Use siteUrl variable in next-sitemap alternateRefs instead of hardcoded URL - Strip query strings and hash fragments in breadcrumb path builder - Wrap fetchStars in useCallback and add to useEffect dependency array - Use dynamic locale for docs link in 404 page - Extract shared formatDate utility to deduplicate blog components Rust/Python fixes: - Rename sender_id → recipient_id in robyn.pyi stubs to match Rust bindings - Remove repr() logging from extract_ws_return to prevent data leakage - Add WsPayload::Close variant to replace "Connection closed" magic string - Switch WebSocket message channel from unbounded to bounded (cap 256) - Log warning when bounded channel is full/closed instead of silently dropping - Propagate registry try_send errors to Python as exceptions instead of swallowing with Ok(()) Made-with: Cursor * fix: normalize SITE_URL, UTC dates, websocket channel lifecycle - Trim trailing slashes from SITE_URL to prevent double-slash URLs - Add timeZone: 'UTC' to formatDate to prevent off-by-one display for negative UTC offsets - Stop cloning message_sender into Python-facing WebSocketConnector clones so the channel properly closes when the actor stops - Send terminal None through channel before dropping sender in stopped() so receive() returns None on disconnect - Consume SendMessage payload by value instead of borrowing and cloning to avoid unnecessary allocations Made-with: Cursor * fix: remove WebSocket binary frame changes from docs-only branch Reverts WebSocket code and doc changes that were accidentally included in the SEO overhaul branch. These belong on feat/binary-websocket-frames. Made-with: Cursor * fix: revert release-CI.yml changes from docs-only branch Made-with: Cursor
1 parent 2e70726 commit 41aafcf

23 files changed

Lines changed: 835 additions & 141 deletions

docs_src/next-sitemap.config.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/** @type {import('next-sitemap').IConfig} */
2+
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://robyn.tech'
3+
4+
module.exports = {
5+
siteUrl,
6+
generateRobotsTxt: false,
7+
generateIndexSitemap: false,
8+
outDir: 'public',
9+
exclude: ['/api/*'],
10+
alternateRefs: [
11+
{
12+
href: siteUrl,
13+
hreflang: 'en',
14+
},
15+
{
16+
href: `${siteUrl}/zh`,
17+
hreflang: 'zh',
18+
},
19+
],
20+
}

docs_src/package-lock.json

Lines changed: 193 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs_src/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"name": "tailwindui-template",
2+
"name": "robyn-website",
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
7-
"build": "next build",
7+
"build": "next build && next-sitemap",
88
"start": "next start",
99
"lint": "next lint"
1010
},
@@ -29,12 +29,14 @@
2929
"feed": "^4.2.2",
3030
"focus-visible": "^5.2.0",
3131
"framer-motion": "^10.12.16",
32+
"gray-matter": "^4.0.3",
3233
"highlight.js": "^11.8.0",
3334
"mdx-annotations": "^0.1.3",
3435
"meilisearch": "^0.33.0",
3536
"next": "13.4.2",
3637
"next-mdx-remote": "^6.0.0",
3738
"next-router-mock": "^0.9.3",
39+
"next-sitemap": "^4.2.3",
3840
"postcss-focus-visible": "^6.0.4",
3941
"prism-themes": "^1.9.0",
4042
"prismjs": "^1.29.0",

docs_src/public/robots.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
User-agent: *
2+
Allow: /
3+
Disallow: /api/
4+
5+
Sitemap: https://robyn.tech/sitemap.xml

0 commit comments

Comments
 (0)