Claude Code के साथ Claude Code Svelte / SvelteKit
Claude Code का उपयोग करके claude code svelte / sveltekit सीखें। Practical tips और code examples शामिल हैं।
SveltedevelopmentでClaude Code use करनाメリット
Svelteはコンパイラベースのframeworkで、कमボイラープレートで高性能なUI build किया जा सकता है。Claude Codeはリアクティブ宣言やSvelteKit固有のrouting・dataロードのpatternを理解し、効率的なcode generateでき है।
Sveltecomponentのgenerate
> Svelteでmodal付きの画像ギャラリーcomponentをबनाओ。
> griddisplay、クリックで拡大、keyボードnavigationsupportで。
<!-- ImageGallery.svelte -->
<script lang="ts">
interface Image {
id: string;
src: string;
alt: string;
thumbnail: string;
}
export let images: Image[] = [];
let selectedIndex = -1;
let isModalOpen = false;
$: selectedImage = selectedIndex >= 0 ? images[selectedIndex] : null;
function openModal(index: number) {
selectedIndex = index;
isModalOpen = true;
}
function closeModal() {
isModalOpen = false;
selectedIndex = -1;
}
function navigate(direction: number) {
selectedIndex = (selectedIndex + direction + images.length) % images.length;
}
function handleKeydown(e: KeyboardEvent) {
if (!isModalOpen) return;
switch (e.key) {
case 'Escape': closeModal(); break;
case 'ArrowLeft': navigate(-1); break;
case 'ArrowRight': navigate(1); break;
}
}
</script>
<svelte:window on:keydown={handleKeydown} />
<div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4">
{#each images as image, i}
<button
class="overflow-hidden rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
on:click={() => openModal(i)}
>
<img
src={image.thumbnail}
alt={image.alt}
class="h-48 w-full object-cover transition-transform hover:scale-105"
loading="lazy"
/>
</button>
{/each}
</div>
{#if isModalOpen && selectedImage}
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80"
on:click={closeModal}
role="dialog"
aria-modal="true"
aria-label="画像拡大display"
>
<div class="relative max-h-[90vh] max-w-[90vw]" on:click|stopPropagation>
<img
src={selectedImage.src}
alt={selectedImage.alt}
class="max-h-[90vh] max-w-[90vw] object-contain"
/>
<button
class="absolute -left-12 top-1/2 -translate-y-1/2 rounded-full bg-white/20 p-2 text-white hover:bg-white/40"
on:click={() => navigate(-1)}
aria-label="पहलेの画像"
>
←
</button>
<button
class="absolute -right-12 top-1/2 -translate-y-1/2 rounded-full bg-white/20 p-2 text-white hover:bg-white/40"
on:click={() => navigate(1)}
aria-label="अगलाの画像"
>
→
</button>
<button
class="absolute -top-10 right-0 text-white hover:text-gray-300"
on:click={closeModal}
aria-label="Close"
>
Close
</button>
</div>
<p class="absolute bottom-4 text-center text-white">
{selectedIndex + 1} / {images.length}
</p>
</div>
{/if}
Svelteストアの設計
> Svelteのストアでthemeとusersettingsをmanagementして。
> localStorage永続化付きで。
// stores/settings.ts
import { writable, derived } from 'svelte/store';
import { browser } from '$app/environment';
interface UserSettings {
theme: 'light' | 'dark' | 'system';
language: 'ja' | 'en';
fontSize: 'sm' | 'md' | 'lg';
sidebarCollapsed: boolean;
}
const defaultSettings: UserSettings = {
theme: 'system',
language: 'ja',
fontSize: 'md',
sidebarCollapsed: false,
};
function createSettingsStore() {
const initial = browser
? JSON.parse(localStorage.getItem('settings') || 'null') || defaultSettings
: defaultSettings;
const { subscribe, set, update } = writable<UserSettings>(initial);
return {
subscribe,
update(partial: Partial<UserSettings>) {
update(current => {
const next = { ...current, ...partial };
if (browser) localStorage.setItem('settings', JSON.stringify(next));
return next;
});
},
reset() {
set(defaultSettings);
if (browser) localStorage.removeItem('settings');
},
};
}
export const settings = createSettingsStore();
// 派生ストア:actually適用されるtheme
export const effectiveTheme = derived(settings, ($settings) => {
if ($settings.theme !== 'system') return $settings.theme;
if (!browser) return 'light';
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
});
SvelteKitのserverサイドfeatures
> SvelteKitでブlogのdataロードとformアクションをimplement करो。
// src/routes/blog/[slug]/+page.server.ts
import type { PageServerLoad, Actions } from './$types';
import { error, fail } from '@sveltejs/kit';
import { prisma } from '$lib/server/db';
export const load: PageServerLoad = async ({ params }) => {
const post = await prisma.post.findUnique({
where: { slug: params.slug },
include: {
author: { select: { name: true, avatar: true } },
comments: {
include: { author: { select: { name: true } } },
orderBy: { createdAt: 'desc' },
},
},
});
if (!post) throw error(404, 'Post not found');
return { post };
};
export const actions: Actions = {
comment: async ({ request, params, locals }) => {
const session = await locals.getSession();
if (!session) return fail(401, { message: 'logインがज़रूरीです' });
const formData = await request.formData();
const body = formData.get('body')?.toString();
if (!body || body.length < 2) {
return fail(400, { message: 'コメントは2文字以ऊपर入力してください', body });
}
await prisma.comment.create({
data: {
body,
postSlug: params.slug,
authorId: session.user.id,
},
});
return { success: true };
},
};
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">
import type { PageData, ActionData } from './$types';
import { enhance } from '$app/forms';
export let data: PageData;
export let form: ActionData;
</script>
<article class="prose mx-auto max-w-3xl">
<h1>{data.post.title}</h1>
<p class="text-gray-500">
{data.post.author.name} - {new Date(data.post.createdAt).toLocaleDateString('en-US')}
</p>
{@html data.post.content}
</article>
<section class="mx-auto mt-12 max-w-3xl">
<h2 class="text-xl font-bold">コメント ({data.post.comments.length})</h2>
<form method="POST" action="?/comment" use:enhance>
<textarea
name="body"
rows="3"
class="mt-4 w-full rounded border p-3"
placeholder="コメントを入力..."
value={form?.body ?? ''}
/>
{#if form?.message}
<p class="text-sm text-red-600">{form.message}</p>
{/if}
<button type="submit" class="mt-2 rounded bg-blue-600 px-4 py-2 text-white">
送信
</button>
</form>
{#each data.post.comments as comment}
<div class="mt-4 rounded border p-4">
<p class="font-medium">{comment.author.name}</p>
<p class="mt-1 text-gray-700">{comment.body}</p>
</div>
{/each}
</section>
test
import { render, fireEvent } from '@testing-library/svelte';
import { describe, it, expect } from 'vitest';
import ImageGallery from './ImageGallery.svelte';
describe('ImageGallery', () => {
const images = [
{ id: '1', src: '/img1.jpg', alt: 'Image 1', thumbnail: '/thumb1.jpg' },
{ id: '2', src: '/img2.jpg', alt: 'Image 2', thumbnail: '/thumb2.jpg' },
];
it('should render all images', () => {
const { getAllByRole } = render(ImageGallery, { props: { images } });
expect(getAllByRole('button')).toHaveLength(2);
});
it('should open modal on click', async () => {
const { getAllByRole, getByRole } = render(ImageGallery, { props: { images } });
await fireEvent.click(getAllByRole('button')[0]);
expect(getByRole('dialog')).toBeTruthy();
});
});
Summary
Claude Code का उपयोग करके、Svelte / SvelteKitのcomponent、ストア、serverサイドロジックをefficientlydevelopmentでき है।Svelteのリアクティブ宣言やSvelteKit固有のloadfunction・formアクションもClaude Codeは正確に扱え है।プロンプトの工夫で品質を高めるコツはプロンプトテクニックcomplete guideをदेखें。framework比較に興味がある方はClaude Code vs GitHub Copilotもदेखें。
Claude Codeके details के लिएAnthropicofficial documentationदेखें。SvelteKitの公式ガイドはSvelteKit公式サイトをदेखें。
Related Posts
Claude Code से अपने Side Projects को Supercharge कैसे करें [Examples के साथ]
Claude Code से personal development projects को dramatically speed up करना सीखें। Real-world examples और idea से deployment तक practical workflow शामिल है।
Claude Code से Refactoring कैसे Automate करें
Claude Code से efficiently code refactoring automate करना सीखें। Real-world projects के लिए practical prompts और concrete refactoring patterns शामिल हैं।
Claude Code के साथ Complete CORS Configuration Guide
Claude Code का उपयोग करके complete CORS configuration guide सीखें। Practical tips और code examples शामिल हैं।