No Login Data Private Local Save

Astro Component Generator - Online .astro Boilerplate

7
0
0
0

Astro Component Generator

Generate .astro boilerplate code instantly — customize props, slots, styles & TypeScript support.

MyComponent.astro 0 lines
Component Configuration
Use PascalCase — this becomes your .astro filename.
A simple reusable UI component with props.
Enable export interface Props with full type safety.
Define props your component accepts. Access via Astro.props.
Add <slot /> for child content injection.
Add a <script> block for client-side interactivity.
Quick Templates
Live Preview BASIC
.astro
MyComponent.astro
---\n// Loading...\n---\n
Frequently Asked Questions About Astro Components
What is an .astro component?

An .astro file is the native component format for the Astro framework. It consists of a frontmatter script section (between --- fences) for server-side logic, and a template section for HTML output. Styles are automatically scoped by default.

How do props work in Astro components?

Props are accessed via the global Astro.props object. With TypeScript, you define an export interface Props { ... } in the frontmatter. Props are passed from parent components using HTML-like attributes, e.g., <MyComponent title="Hello" />.

What are Astro slots?

Slots allow you to inject child content into a component. The default <slot /> renders all child content. Named slots like <slot name="header" /> let you target specific content areas. Slots can also have fallback content.

Can I use TypeScript in .astro files?

Yes! Astro has first-class TypeScript support. Simply use TypeScript syntax inside the frontmatter --- fences. You can define interface Props, use type annotations, and import typed modules — all without extra configuration.

How does styling work in Astro?

Styles inside <style> tags are automatically scoped to the component. You can also use <style lang="scss"> for SCSS, or <style is:global> for global styles. Tailwind CSS integrates seamlessly via the Astro Tailwind integration.

Are Astro components static or dynamic?

By default, Astro components render at build time (static). For client-side interactivity, you can add <script> tags, or use client directives like client:load when embedding UI framework components (React, Vue, Svelte, etc.).

What's the naming convention for .astro files?

The convention is PascalCase for component files (e.g., HeroBanner.astro, BlogCard.astro). Layout files often use lowercase (e.g., layout.astro). The file name becomes the component name when imported.

How do I share state between Astro components?

State can be shared via props drilling, Astro global stores, or by using Nano Stores (the recommended state management library for Astro). For framework components, you can also use their native state management solutions.

'); } return lines.join('\n'); } function updateCode() { const code = generateCode(); const escaped = escapeHTML(code); $('#ast-code-inner').html(escaped); const lineCount = code.split('\n').length; $('#ast-line-num').text(lineCount); // Update filename const fname = toPascal(getCompName()) + '.astro'; $('#ast-filename-text').text(fname); $('#ast-preview-fname').text(fname); $('#ast-download-link').attr('download', fname); // Badge const compType = $('#ast-comp-type').val(); $('#ast-badge-type').text(badgeLabels[compType] || 'BASIC'); } function copyCode() { const code = generateCode(); if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(code).then(() => { showToast('✅ Code copied to clipboard!', 'success'); }).catch(() => { fallbackCopy(code); }); } else { fallbackCopy(code); } } function fallbackCopy(text) { const ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.left = '-9999px'; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); showToast('✅ Code copied!', 'success'); } catch (e) { showToast('❌ Copy failed. Please try again.', ''); } document.body.removeChild(ta); } function downloadFile() { const code = generateCode(); const fname = toPascal(getCompName()) + '.astro'; const blob = new Blob([code], { type: 'text/plain;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = fname; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showToast('📥 Downloaded ' + fname, 'success'); } function applyPreset(preset) { switch(preset) { case 'blog-card': $('#ast-comp-name').val('BlogCard'); $('#ast-comp-type').val('card'); $('#ast-use-ts').prop('checked', true); $('#ast-style-type').val('css'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', true); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = [ { name: 'title', type: 'string', required: true, defaultVal: '' }, { name: 'description', type: 'string', required: true, defaultVal: '' }, { name: 'image', type: 'string', required: false, defaultVal: '\'/default-blog.jpg\'' }, { name: 'date', type: 'string', required: false, defaultVal: '\'2024-01-01\'' }, { name: 'tags', type: 'array', required: false, defaultVal: '[]' } ]; break; case 'navbar': $('#ast-comp-name').val('Navbar'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', true); $('#ast-style-type').val('tailwind'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', true); $('#ast-has-named-slots').prop('checked', true); $('#ast-has-script').prop('checked', true); propsList = [ { name: 'brandName', type: 'string', required: true, defaultVal: '\'MySite\'' }, { name: 'links', type: 'array', required: false, defaultVal: '[]' }, { name: 'isSticky', type: 'boolean', required: false, defaultVal: 'false' } ]; break; case 'footer': $('#ast-comp-name').val('SiteFooter'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', false); $('#ast-style-type').val('css'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', false); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = [ { name: 'copyright', type: 'string', required: false, defaultVal: '\'2024 My Company\'' }, { name: 'links', type: 'array', required: false, defaultVal: '[]' } ]; break; case 'seo-head': $('#ast-comp-name').val('SEOHead'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', true); $('#ast-style-type').val('none'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', false); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = [ { name: 'title', type: 'string', required: true, defaultVal: '' }, { name: 'description', type: 'string', required: true, defaultVal: '' }, { name: 'ogImage', type: 'string', required: false, defaultVal: '\'/og-default.jpg\'' }, { name: 'canonicalURL', type: 'string', required: false, defaultVal: '' } ]; break; case 'button': $('#ast-comp-name').val('AstroButton'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', true); $('#ast-style-type').val('css'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', true); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = [ { name: 'variant', type: 'string', required: false, defaultVal: '\'primary\'' }, { name: 'size', type: 'string', required: false, defaultVal: '\'md\'' }, { name: 'disabled', type: 'boolean', required: false, defaultVal: 'false' }, { name: 'href', type: 'string', required: false, defaultVal: '' } ]; break; case 'empty': $('#ast-comp-name').val('NewComponent'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', false); $('#ast-style-type').val('none'); $('#ast-has-props').prop('checked', false); $('#ast-has-slot').prop('checked', false); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = []; break; default: break; } renderPropRows(); updateCode(); updateSlotVisibility(); $('#ast-type-desc').text(typeDescriptions[$('#ast-comp-type').val()] || ''); } function updateSlotVisibility() { const hasSlot = $('#ast-has-slot').is(':checked'); if (hasSlot) { $('#ast-slot-options').slideDown(200); } else { $('#ast-slot-options').slideUp(200); $('#ast-has-named-slots').prop('checked', false); } } function resetAll() { $('#ast-comp-name').val('MyComponent'); $('#ast-comp-type').val('basic'); $('#ast-use-ts').prop('checked', true); $('#ast-style-type').val('css'); $('#ast-has-props').prop('checked', true); $('#ast-has-slot').prop('checked', false); $('#ast-has-named-slots').prop('checked', false); $('#ast-has-script').prop('checked', false); propsList = [ { name: 'title', type: 'string', required: true, defaultVal: '' }, { name: 'class', type: 'string', required: false, defaultVal: '' } ]; renderPropRows(); updateCode(); updateSlotVisibility(); $('#ast-type-desc').text(typeDescriptions['basic']); } // --- Event Bindings --- $('#ast-comp-name').on('input', function() { const pascal = toPascal($(this).val()); if (pascal && $(this).val() !== pascal) { // Optionally auto-correct, but let's leave it flexible } updateCode(); }); $('#ast-comp-type').on('change', function() { const val = $(this).val(); $('#ast-type-desc').text(typeDescriptions[val] || ''); $('#ast-badge-type').text(badgeLabels[val] || 'BASIC'); // Auto-enable slots for layout type if (val === 'layout') { $('#ast-has-slot').prop('checked', true); updateSlotVisibility(); } updateCode(); }); $('#ast-use-ts, #ast-style-type, #ast-has-props, #ast-has-slot, #ast-has-named-slots, #ast-has-script') .on('change', function() { if ($(this).attr('id') === 'ast-has-slot') updateSlotVisibility(); updateCode(); }); $('#ast-has-slot').on('change', function() { updateSlotVisibility(); updateCode(); }); // Props container events $('#ast-props-container').on('input change', '.prop-name, .prop-type, .prop-required, .prop-default', function() { syncPropsFromDOM(); updateCode(); }); $('#ast-props-container').on('click', '.prop-delete', function() { const $row = $(this).closest('.ast-prop-row'); $row.slideUp(200, function() { $row.remove(); syncPropsFromDOM(); updateCode(); }); }); $('#ast-add-prop-btn').on('click', function() { addProp(); }); // Action buttons $('#ast-copy-btn, #ast-copy-preview-btn').on('click', function(e) { e.preventDefault(); copyCode(); }); $('#ast-download-btn').on('click', function(e) { e.preventDefault(); downloadFile(); }); $('#ast-reset-btn').on('click', function(e) { e.preventDefault(); resetAll(); showToast('🔄 Reset to defaults', ''); }); // Presets $('.preset-btn').on('click', function() { const preset = $(this).data('preset'); applyPreset(preset); showToast('✨ Template applied: ' + $(this).text().trim(), 'success'); }); // Keyboard shortcut for copy $(document).on('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 'c' && document.activeElement && document.activeElement.id === 'ast-code-output') { // User is selecting text in the code preview, let them use native copy return; } if ((e.ctrlKey || e.metaKey) && e.key === 's' && $('#astro-gen').length && $('#astro-gen').is(':visible')) { e.preventDefault(); downloadFile(); } }); // --- Init --- renderPropRows(); updateSlotVisibility(); updateCode(); $('#ast-type-desc').text(typeDescriptions['basic']); console.log('🚀 Astro Component Generator ready — build fast .astro boilerplate!'); })();