google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
inertia-rails-ssr
Set up Server-Side Rendering (SSR) for Inertia Rails applications. Use when you need SEO optimization, faster initial page loads, or support for users with JavaScript disabled.
Full skill instructions
Server-Side Rendering pre-renders JavaScript pages on the server, delivering fully rendered HTML to visitors. This improves SEO, enables faster initial page loads, and allows basic navigation even with JavaScript disabled.
@vue/server-renderer separately for older versions)Create app/frontend/ssr/ssr.js:
Vue 3:
import { createInertiaApp } from '@inertiajs/vue3'
import createServer from '@inertiajs/vue3/server'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'
const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
createServer((page) =>
createInertiaApp({
page,
render: renderToString,
resolve: (name) => {
const page = pages[`../pages/${name}.vue`]
if (!page) {
throw new Error(`Page not found: ${name}`)
}
return page
},
setup({ App, props, plugin }) {
return createSSRApp({
render: () => h(App, props),
}).use(plugin)
},
})
)
React:
import { createInertiaApp } from '@inertiajs/react'
import createServer from '@inertiajs/react/server'
import ReactDOMServer from 'react-dom/server'
const pages = import.meta.glob('../pages/**/*.jsx', { eager: true })
createServer((page) =>
createInertiaApp({
page,
render: ReactDOMServer.renderToString,
resolve: (name) => {
const page = pages[`../pages/${name}.jsx`]
if (!page) {
throw new Error(`Page not found: ${name}`)
}
return page
},
setup: ({ App, props }) => <App {...props} />,
})
)
Update config/vite.json:
{
"all": {
"sourceCodeDir": "app/frontend",
"entrypointsDir": "entrypoints"
},
"development": {
"autoBuild": true
},
"production": {
"ssrBuildEnabled": true
}
}
Update config/initializers/inertia_rails.rb:
InertiaRails.configure do |config|
# Enable SSR only when Vite is configured for it
config.ssr_enabled = ViteRuby.config.ssr_build_enabled
# SSR server URL (default)
config.ssr_url = 'http://localhost:13714'
end
Modify app/frontend/entrypoints/application.js for hydration:
Vue 3:
import { createInertiaApp } from '@inertiajs/vue3'
import { createSSRApp, h } from 'vue'
const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
createInertiaApp({
resolve: (name) => pages[`../pages/${name}.vue`],
setup({ el, App, props, plugin }) {
// Use createSSRApp instead of createApp for hydration
createSSRApp({
render: () => h(App, props),
})
.use(plugin)
.mount(el)
},
})
React:
import { createInertiaApp } from '@inertiajs/react'
import { hydrateRoot } from 'react-dom/client'
const pages = import.meta.glob('../pages/**/*.jsx', { eager: true })
createInertiaApp({
resolve: (name) => pages[`../pages/${name}.jsx`],
setup({ el, App, props }) {
// Use hydrateRoot instead of createRoot for SSR
hydrateRoot(el, <App {...props} />)
},
})
Add SSR head injection to your layout:
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csp_meta_tag %>
<%= inertia_ssr_head %>
<%= vite_client_tag %>
<%= vite_javascript_tag 'application' %>
</head>
<body>
<%= yield %>
</body>
</html>
# Build both client and SSR bundles
bin/vite build
bin/vite build --ssr
# Start the SSR server
bin/vite ssr
Create /etc/systemd/system/inertia-ssr.service:
[Unit]
Description=Inertia SSR Server
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/myapp/current
ExecStart=/usr/bin/node public/vite-ssr/ssr.js
Restart=on-failure
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
sudo systemctl enable inertia-ssr
sudo systemctl start inertia-ssr
pm2 start public/vite-ssr/ssr.js --name inertia-ssr
pm2 save
# Run SSR server alongside Rails
CMD ["sh", "-c", "node public/vite-ssr/ssr.js & bundle exec puma"]
For better performance on multi-core systems (requires @inertiajs/core v2.0.7+):
// ssr/ssr.js
createServer(
(page) => createInertiaApp({ /* ... */ }),
{ cluster: true } // Enable clustering
)
This runs multiple Node.js processes on a single port using round-robin request handling.
createServer(
(page) => createInertiaApp({ /* ... */ }),
{ port: 13715 } // Custom port
)
Update Rails config to match:
config.ssr_url = 'http://localhost:13715'
Enable SSR only for specific routes:
class ApplicationController < ActionController::Base
# Disable SSR for admin pages
inertia_config(ssr_enabled: false)
end
class PagesController < ApplicationController
# Enable SSR for public pages
inertia_config(ssr_enabled: Rails.env.production?)
end
Set meta tags in your controller:
class PostsController < ApplicationController
def show
post = Post.find(params[:id])
render inertia: {
post: post.as_json(only: [:id, :title, :content])
}, meta: {
title: post.title,
description: post.excerpt,
og_image: post.cover_image_url
}
end
end
Vue 3:
<script setup>
import { Head } from '@inertiajs/vue3'
defineProps(['post'])
</script>
<template>
<Head>
<title>{{ post.title }}</title>
<meta name="description" :content="post.excerpt" />
<meta property="og:title" :content="post.title" />
<meta property="og:image" :content="post.coverImageUrl" />
</Head>
<article>
<h1>{{ post.title }}</h1>
<!-- ... -->
</article>
</template>
React:
import { Head } from '@inertiajs/react'
export default function Show({ post }) {
return (
<>
<Head>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
<meta property="og:title" content={post.title} />
</Head>
<article>
<h1>{post.title}</h1>
{/* ... */}
</article>
</>
)
}
createInertiaApp({
title: (title) => title ? `${title} - My App` : 'My App',
// ...
})
curl http://localhost:13714journalctl -u inertia-ssr -fonMounted)// Bad - different on server vs client
const time = new Date().toLocaleTimeString()
// Good - render after mount
const time = ref(null)
onMounted(() => {
time.value = new Date().toLocaleTimeString()
})
Ensure CSS is included in the SSR bundle or use critical CSS extraction.
# Log slow SSR renders
around_action :track_ssr_time, if: -> { request.inertia? }
def track_ssr_time
start = Time.current
yield
duration = Time.current - start
Rails.logger.info "SSR render: #{duration.round(3)}s" if duration > 0.1
end
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.