Files
nuc/docs/publishing-artifacts.md
Alejandro Gutiérrez f56528ddcd Slim CLAUDE.md from 65K to 21K by splitting app-specific docs
Move OpenClaw, Palmr, MinIO, JSX publishing, MCP configs, and migration
candidates into dedicated docs/ files. Keep only DevOps-essential content
inline (deployment rules, DNS, router, credentials, troubleshooting).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 02:56:08 +00:00

3.8 KiB

Publishing JSX/React Artifacts Online

Single-file React components (JSX) can be published as standalone web pages via the NUC's artifacts infrastructure.

How It Works

Public Internet → Tailscale Funnel (:443) → Traefik → artifacts-web (nginx) → /opt/artifacts/
  • Funnel URL: https://alezmad-nuc.tail58f5ad.ts.net/artifacts/<name>/
  • LAN URL: https://artifacts.nuc.lan/<name>/
  • Nginx container: artifacts-web (image: nginx:alpine, read-only mount of /opt/artifacts)
  • Traefik public route: Host(alezmad-nuc.tail58f5ad.ts.net) && PathPrefix(/artifacts) → strips /artifactsartifacts-web:80
  • Config file: /traefik/dynamic/nuc-services-public.yaml (inside coolify-proxy container)

Quick Publish Steps

# 1. Build self-contained HTML from JSX
#    - Replace `import { useState, ... } from "react"` with `const { useState, ... } = React;`
#    - Remove `export default ComponentName;`
#    - Wrap in HTML with React 18 CDN + Babel standalone
#    - Add `ReactDOM.createRoot(root).render(<Component />)` at the end

# 2. Copy to NUC artifacts directory
ssh nuc "echo '7vXHpSTD.' | sudo -S mkdir -p /opt/artifacts/<name>"
scp /tmp/build/index.html nuc:~/tmp-artifact.html
ssh nuc "echo '7vXHpSTD.' | sudo -S mv ~/tmp-artifact.html /opt/artifacts/<name>/index.html"
ssh nuc "echo '7vXHpSTD.' | sudo -S chmod 644 /opt/artifacts/<name>/index.html"

# 3. Done! No server restart needed — nginx serves it immediately.

HTML Template for JSX Files

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TITLE</title>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
  <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: #08090d; overflow-x: hidden; }
    /* Add any @keyframes or global styles here */
  </style>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    const { useState, useEffect, useRef, useCallback } = React;

    // ... paste JSX component code here (without import/export lines) ...

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(React.createElement(ComponentName));
  </script>
</body>
</html>

Build Script (for large JSX files)

# Automated: strips import/export, wraps in HTML
cat > /tmp/build.html << 'HEADER'
<!DOCTYPE html>
<html><head>
  <meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
  <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head><body><div id="root"></div>
<script type="text/babel">
const { useState, useEffect, useRef, useCallback, useMemo, useReducer } = React;
HEADER

# Strip first line (import) and last line (export), append body
sed -n '2,$p' source.jsx | sed '$d' >> /tmp/build.html

# Add render footer (replace COMPONENT_NAME)
cat >> /tmp/build.html << 'FOOTER'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement(COMPONENT_NAME));
</script></body></html>
FOOTER

Currently Published

Path Source Public URL
/opt/artifacts/checkin/ arrio/.scratch/checkin_demo_v1.jsx https://alezmad-nuc.tail58f5ad.ts.net/artifacts/checkin/