Claude Code Svelte / SvelteKit dengan Claude Code
Pelajari tentang claude code svelte / sveltekit menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.
SveltepengembanganでClaude Codeを使うメリット
Svelte compilerベース framework 、少 tidakボイラープレート 高性能なUI pembangunan bisa dilakukan.Claude Code リアクティブ宣言やSvelteKit固有 routing・データロード pola 理解し、efisienなコード generate bisa dilakukan.
generate Sveltekomponen
> Svelte dengan modal付き gambargalerikomponen buatkan.
> gridtampilan、クリック dengan 拡大、キーボードnavigasidukungan dengan 。
<!-- 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="gambar拡大tampilan"
>
<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="前 gambar"
>
←
</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="次 gambar"
>
→
</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}
設計 Sveltestore
> Svelte store dengan tema dan penggunapengaturan manajemenして。
> localStoragepersistensi付き dengan 。
// 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();
// 派生store:実際 適用されるtema
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';
});
serverサイド機能 SvelteKit
> SvelteKit dengan ブログ データロード dan formアクション implementasikan.
// 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: 'login diperlukan す' });
const formData = await request.formData();
const body = formData.get('body')?.toString();
if (!body || body.length < 2) {
return fail(400, { message: 'コメント 2文字以上input ください', 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="コメント input..."
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>
Testing
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
Dengan Claude Code, Svelte / SvelteKit komponen、store、serverサイドロジック efisien pengembangan bisa dilakukan.Svelte リアクティブ宣言やSvelteKit固有 loadfungsi・formアクション juga Claude Code 正確 扱え.プロンプト 工夫 品質 高めるコツ プロンプトテクニック完全panduan silakan lihat.framework比較 興味 ada方 Claude Code vs GitHub Copilot juga ご覧.
Untuk Claude Codeの詳細はAnthropic公式dokumenをご覧ください。SvelteKitの公式panduan, lihat SvelteKit公式サイト.
Related Posts
Cara Mempercepat Side Project dengan Claude Code [Dengan Contoh]
Pelajari cara mempercepat project development personal secara drastis menggunakan Claude Code. Dilengkapi contoh nyata dan workflow praktis dari ide hingga deployment.
Cara Mengotomatisasi Refactoring dengan Claude Code
Pelajari cara mengotomatisasi code refactoring secara efisien menggunakan Claude Code. Dilengkapi prompt praktis dan pola refactoring konkret untuk project nyata.
Panduan Lengkap Konfigurasi CORS dengan Claude Code
Pelajari tentang panduan lengkap konfigurasi CORS menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.