Agent Skills by ALSEL
Anthropic ClaudeEC・マーケティング⭐ リポ 299品質スコア 89/100

url-routing-patterns

URLの構造設計、スラッグ生成、SEOフレンドリーなURL、リダイレクト、多言語対応のURLパターンを設計する際に利用します。ルート設定、URLの書き換え、正規URLの指定、ヘッドレスCMSのルーティングAPIに対応しています。

description の原文を見る

Use when designing URL structures, slug generation, SEO-friendly URLs, redirects, or localized URL patterns. Covers route configuration, URL rewriting, canonical URLs, and routing APIs for headless CMS.

SKILL.md 本文

URLルーティングパターン

ヘッドレスCMSアーキテクチャにおけるURL構造の設計、スラッグ生成、ルーティング戦略に関するガイダンスです。

このスキルを使用する場合

  • SEOフレンドリーなURL構造を設計する
  • スラッグ生成を実装する
  • リダイレクト管理を設定する
  • ローカライズされたURLパターンを計画する
  • ルーティングAPIを構築する

URL構造パターン

階層型URL(ページベース)

/                           # Home
/about                      # About page
/about/team                 # Team (child of About)
/about/team/leadership      # Leadership (grandchild)
/products                   # Products listing
/products/software          # Software category
/products/software/crm      # Specific product

コンテンツタイプURL(コレクションベース)

/blog                       # Blog listing
/blog/2025/01/my-article    # Blog post with date
/blog/my-article            # Blog post without date

/docs                       # Documentation home
/docs/getting-started       # Doc section
/docs/getting-started/install # Doc page

/team/jane-doe              # Team member profile
/portfolio/project-alpha    # Portfolio item

ハイブリッドURL

/products/software/crm      # Category > Product
/blog/technology/ai-trends  # Category > Post
/help/faq/billing           # Section > Topic

スラッグ生成

スラッグサービス

public class SlugService
{
    public string GenerateSlug(string text, SlugOptions? options = null)
    {
        options ??= new SlugOptions();

        var slug = text
            .ToLowerInvariant()
            .Normalize(NormalizationForm.FormD);

        // Remove diacritics
        slug = new string(slug
            .Where(c => CharUnicodeInfo.GetUnicodeCategory(c)
                != UnicodeCategory.NonSpacingMark)
            .ToArray());

        // Replace spaces and invalid chars
        slug = Regex.Replace(slug, @"[^a-z0-9\s-]", "");
        slug = Regex.Replace(slug, @"\s+", "-");
        slug = Regex.Replace(slug, @"-+", "-");
        slug = slug.Trim('-');

        // Enforce max length
        if (slug.Length > options.MaxLength)
        {
            slug = slug.Substring(0, options.MaxLength).TrimEnd('-');
        }

        return slug;
    }

    public async Task<string> GenerateUniqueSlugAsync(
        string text,
        string contentType,
        Guid? excludeId = null)
    {
        var baseSlug = GenerateSlug(text);
        var slug = baseSlug;
        var counter = 1;

        while (await SlugExistsAsync(slug, contentType, excludeId))
        {
            slug = $"{baseSlug}-{counter}";
            counter++;
        }

        return slug;
    }
}

public class SlugOptions
{
    public int MaxLength { get; set; } = 100;
    public bool AllowUnicode { get; set; } = false;
    public string Separator { get; set; } = "-";
}

オートルートパターン

public class AutorouteSettings
{
    public string Pattern { get; set; } = string.Empty;
    public bool AllowCustom { get; set; } = true;
    public bool ShowHomepageOption { get; set; }
}

// Pattern examples:
// "{ContentType}/{Slug}"           -> /article/my-title
// "{Category.Slug}/{Slug}"         -> /technology/my-article
// "blog/{CreatedUtc.Year}/{Slug}"  -> /blog/2025/my-article
// "{Parent.Path}/{Slug}"           -> /about/team/leadership

public class AutorouteService
{
    public string GeneratePath(ContentItem item, string pattern)
    {
        var path = pattern;

        // Replace tokens
        path = path.Replace("{Slug}", item.Slug);
        path = path.Replace("{ContentType}", item.ContentType.ToLower());
        path = path.Replace("{CreatedUtc.Year}", item.CreatedUtc.Year.ToString());
        path = path.Replace("{CreatedUtc.Month}",
            item.CreatedUtc.Month.ToString("00"));

        // Handle relationships
        if (path.Contains("{Category.Slug}") && item.CategoryId.HasValue)
        {
            var category = _categoryRepository.Get(item.CategoryId.Value);
            path = path.Replace("{Category.Slug}", category?.Slug ?? "uncategorized");
        }

        // Handle parent path
        if (path.Contains("{Parent.Path}") && item.ParentId.HasValue)
        {
            var parent = _contentRepository.Get(item.ParentId.Value);
            path = path.Replace("{Parent.Path}", parent?.Path ?? "");
        }

        // Normalize path
        path = "/" + path.Trim('/').ToLowerInvariant();
        return path;
    }
}

リダイレクト管理

リダイレクトタイプ

public class Redirect
{
    public Guid Id { get; set; }
    public string FromPath { get; set; } = string.Empty;
    public string ToPath { get; set; } = string.Empty;
    public RedirectType Type { get; set; }
    public bool IsRegex { get; set; }
    public bool PreserveQueryString { get; set; }
    public DateTime? ExpiresUtc { get; set; }
}

public enum RedirectType
{
    Permanent = 301,    // Moved permanently (SEO transfers)
    Temporary = 302,    // Found (temporary redirect)
    SeeOther = 303,     // See other (POST to GET)
    TemporaryRedirect = 307, // Temporary (preserves method)
    PermanentRedirect = 308  // Permanent (preserves method)
}

スラッグ変更時の自動リダイレクト

public class ContentUpdateHandler
{
    public async Task HandleSlugChangeAsync(
        Guid contentId,
        string oldPath,
        string newPath)
    {
        if (oldPath == newPath) return;

        // Create redirect from old to new
        var redirect = new Redirect
        {
            Id = Guid.NewGuid(),
            FromPath = oldPath,
            ToPath = newPath,
            Type = RedirectType.Permanent,
            PreserveQueryString = true
        };

        await _redirectRepository.AddAsync(redirect);

        // Update any existing redirects pointing to old path
        var existingRedirects = await _redirectRepository
            .GetByToPathAsync(oldPath);

        foreach (var existing in existingRedirects)
        {
            existing.ToPath = newPath;
            await _redirectRepository.UpdateAsync(existing);
        }
    }
}

ローカライズされたURL

URLローカライズ戦略

戦略メリットデメリット
パスプレフィックス/en/about, /fr/about明確でSEOフレンドリーURLが長い
サブドメインen.site.com, fr.site.comホスティングを分離可能セットアップが複雑
クエリパラメータ/about?lang=frシンプルSEOに不利
翻訳されたスラッグ/about, /a-propos自然管理が難しい

パスプレフィックス実装

public class LocalizedRoutingService
{
    private readonly string[] _supportedLocales = { "en", "fr", "de", "es" };
    private readonly string _defaultLocale = "en";

    public string GetLocalizedPath(string path, string locale)
    {
        // Remove existing locale prefix
        var cleanPath = RemoveLocalePrefix(path);

        // Add new locale prefix (skip for default)
        if (locale != _defaultLocale)
        {
            return $"/{locale}{cleanPath}";
        }

        return cleanPath;
    }

    public (string path, string locale) ParseLocalizedPath(string requestPath)
    {
        foreach (var locale in _supportedLocales)
        {
            if (requestPath.StartsWith($"/{locale}/") ||
                requestPath == $"/{locale}")
            {
                var path = requestPath.Substring(locale.Length + 1);
                return (string.IsNullOrEmpty(path) ? "/" : path, locale);
            }
        }

        return (requestPath, _defaultLocale);
    }
}

Hreflangタグ

public class HreflangService
{
    public List<HreflangTag> GenerateHreflangTags(
        ContentItem content,
        string baseUrl)
    {
        var tags = new List<HreflangTag>();

        // Get all localized versions
        var localizations = _localizationService
            .GetLocalizedVersions(content.Id);

        foreach (var loc in localizations)
        {
            tags.Add(new HreflangTag
            {
                Hreflang = loc.Locale,
                Href = $"{baseUrl}{GetLocalizedPath(content.Path, loc.Locale)}"
            });
        }

        // Add x-default
        tags.Add(new HreflangTag
        {
            Hreflang = "x-default",
            Href = $"{baseUrl}{content.Path}"
        });

        return tags;
    }
}

public class HreflangTag
{
    public string Hreflang { get; set; } = string.Empty;
    public string Href { get; set; } = string.Empty;
}

カノニカルURL

public class CanonicalUrlService
{
    public string GetCanonicalUrl(HttpRequest request, ContentItem content)
    {
        var baseUrl = $"{request.Scheme}://{request.Host}";

        // Use content's primary path as canonical
        var canonicalPath = content.PrimaryPath ?? content.Path;

        // Remove query parameters (unless paginated)
        // Normalize trailing slash

        return $"{baseUrl}{canonicalPath}";
    }
}

URL正規化

public class UrlNormalizer
{
    public string Normalize(string url, NormalizationOptions options)
    {
        var uri = new UriBuilder(url);

        // Lowercase path
        uri.Path = uri.Path.ToLowerInvariant();

        // Handle trailing slash
        if (options.TrailingSlash == TrailingSlashBehavior.Remove)
        {
            uri.Path = uri.Path.TrimEnd('/');
        }
        else if (options.TrailingSlash == TrailingSlashBehavior.Add &&
                 !uri.Path.EndsWith('/'))
        {
            uri.Path += '/';
        }

        // Sort query parameters
        if (options.SortQueryParams && !string.IsNullOrEmpty(uri.Query))
        {
            var queryParams = HttpUtility.ParseQueryString(uri.Query);
            var sorted = queryParams.AllKeys
                .OrderBy(k => k)
                .Select(k => $"{k}={queryParams[k]}");
            uri.Query = string.Join("&", sorted);
        }

        return uri.ToString();
    }
}

public class NormalizationOptions
{
    public TrailingSlashBehavior TrailingSlash { get; set; }
    public bool SortQueryParams { get; set; }
    public bool ForceLowercase { get; set; } = true;
}

public enum TrailingSlashBehavior
{
    Remove,
    Add,
    Preserve
}

ルーティングAPI

エンドポイント

GET /api/routes/resolve?path=/about/team  # Resolve path to content
GET /api/redirects                        # List redirects
GET /api/sitemap.xml                      # XML sitemap
POST /api/slugs/generate                  # Generate slug from text
POST /api/slugs/validate                  # Check slug availability

ルート解決レスポンス

{
  "data": {
    "path": "/about/team",
    "contentId": "page-456",
    "contentType": "Page",
    "locale": "en",
    "canonical": "https://example.com/about/team",
    "alternates": [
      { "hreflang": "fr", "href": "https://example.com/fr/a-propos/equipe" },
      { "hreflang": "de", "href": "https://example.com/de/uber-uns/team" }
    ],
    "breadcrumbs": [
      { "label": "Home", "path": "/" },
      { "label": "About", "path": "/about" },
      { "label": "Team", "path": "/about/team" }
    ]
  }
}

関連スキル

  • page-structure-design - URLのページ階層
  • navigation-architecture - メニューリンクとパス
  • headless-api-design - ルーティングAPIエンドポイント

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
majiayu000
リポジトリ
majiayu000/claude-skill-registry
ライセンス
MIT
最終更新
2026/5/4

Source: https://github.com/majiayu000/claude-skill-registry / ライセンス: MIT

関連スキル

Anthropic ClaudeEC・マーケティング⭐ リポ 6,400

seo-maps

ローカルSEO向けのマップインテリジェンス機能です。ジオグリッドのランク追跡、APIを通じたGBPプロフィール監査、Google・Tripadvisor・Trustpilotなど複数プラットフォームのレビュー分析、Google・Bing・Apple・OSM間のNAP(名前・住所・電話番号)検証、競合他社の半径マッピング、APIデータからのLocalBusinessスキーマ生成が可能です。3段階の機能レベルで対応でき、無料版(Overpass + Geoapify)、DataForSEO(フル機能)、DataForSEO + Google(最大カバレッジ)から選択できます。「maps」「geo-grid」「rank tracking」「GBP audit」「review velocity」「competitor radius」「maps analysis」「local rank tracking」「Share of Local Voice」「SoLV」などのキーワードで利用できます。

by AgriciDaniel
Anthropic ClaudeEC・マーケティング⭐ リポ 6,400

seo-content-brief

セクションごとの文字数、競合スコアリング、キーワード密度ガイダンス、ページタイプテンプレートを含む競争力のあるSEOコンテンツブリーフを生成します。新規ページのブリーフと既存ページの改善ブリーフの両方に対応しています。ユーザーが「コンテンツブリーフ」「ブリーフを作成」「コンテンツアウトライン」「ブログブリーフ」「サービスページブリーフ」「ブリーフ〜」「ライティングブリーフ」「コンテンツプラン」「アウトライン〜」などと言った場合に使用します。

by AgriciDaniel
ALSEL独自Anthropic ClaudeEC・マーケティング

rakuten-seo

楽天市場の商品名・キャッチコピーをSEO最適化するスキル。「楽天SEO」「商品名最適化」「楽天の商品名」「キャッチコピー」「楽天のタイトル」「商品名を直して」「楽天検索対策」など、楽天市場の商品名やキャッチコピーの作成・改善・チェックに関するリクエストで必ずこのスキルを使う。既存の商品名の改善も、ゼロからの作成も対応。あらゆるジャンル(食品・ファッション・化粧品・家電・サプリ・インテリア・ベビー・ペット・業務用など)に対応。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

amazon-seo-jp

Amazon.co.jp商品ページのSEO分析・最適化・自動採点スキル v2.0。 COSMO/Rufus/A10アルゴリズムに基づく採点。セラーセントラル出品レポート(.xlsm)を入力すると、 商品タイトル・箇条書き・検索キーワード・商品説明文を100点満点で採点し、 4項目すべての改善案を日本語で出力する。 トリガー: 「Amazon SEO」「商品ページ採点」「Amazon最適化」 「リスティング改善」「Amazon商品名」「箇条書き改善」 「COSMO対応」「Rufus最適化」「Amazon タイトル」 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

rakuten-bulk-control-csv

楽天RMSの一括登録/一括除外/一括更新用CSV(コントロールカラム,商品管理番号 の2列フォーマット)を作成するスキル。商品DL CSV・商品管理画面のコピペ・Excel・PDFなどから商品管理番号を抽出し、Shift-JIS+LF改行で出力する。「一括除外リスト作って」「楽天の除外CSV」「コントロールカラムnで」「2800円以下の商品をdで」「在庫0の商品を一括削除」「商品管理番号抜いてshift-jsで」「このフォーマットで」など、楽天RMSの商品一括処理用CSVを作るタスクで必ずこのスキルを使う。コントロールカラム値(n=新規/d=削除/u=更新)と抽出条件(全件・価格・在庫・販売状態など)をユーザー指示に応じて柔軟に切り替える。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
ALSEL独自Anthropic ClaudeEC・マーケティング

amazon-a-plus-content-brief

Amazon A+コンテンツの構成・モジュール選定・画像指示・比較表・FAQを設計するスキル。「A+コンテンツ作って」「Aプラス構成」「ブランドストーリー」「比較表つきA+」「A+モジュール選定」「Amazonのページに画像入れたい」「A+のヘッダー画像」「A+コンテンツマネージャー」など、Amazon A+コンテンツの企画・設計・改善のリクエストで必ずこのスキルを使う。ベーシック17モジュール/Premium追加機能/画像サイズ規定/文字数目安/審査リジェクト要因を踏まえて、デザイナーに渡せるブリーフ形式で出力。あらゆるジャンル(家電・コスメ・食品・アパレル・日用品・ベビー・ペット等)に対応。※ブランドストア(マルチページ)の設計は別スキル `amazon-brand-store-planner`、タイトル・bullet改善は `amazon-title-bullet-rewriter-jp`、メイン画像のチェックは `amazon-main-image-checker`。 【ALSEL独自スキル】株式会社ALSEL が、19年・5,000社超の EC 支援で得たノウハウをもとに開発したオリジナルスキルです。

by 株式会社ALSEL
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: majiayu000 · majiayu000/claude-skill-registry · ライセンス: MIT