Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when building Laravel emails — Mailables, Markdown templates, queued sending, attachments, previews — even when the user says 'send this as an email' without naming Mailables.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Use this skill when building email functionality:
For simple notification emails (one-off messages), see laravel-notifications. Use Mailables when you need full control over the email template.
app/Mail/ for naming, base class, queueing convention, and the templates in resources/views/emails/ for the project's markdown style.php artisan make:mail InvoiceMail --markdown=emails.invoice.ShouldQueue).resources/views/emails/.php artisan make:mail InvoiceMail --markdown=emails.invoice
declare(strict_types=1);
namespace App\Mail;
use App\Models\Invoice;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class InvoiceMail extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
public function __construct(
private readonly Invoice $invoice,
) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Invoice #' . $this->invoice->getNumber(),
replyTo: ['billing@example.com'],
);
}
public function content(): Content
{
return new Content(
markdown: 'emails.invoice',
with: [
'invoice' => $this->invoice,
'url' => route('invoices.show', $this->invoice->getId()),
],
);
}
/** @return array<int, \Illuminate\Mail\Mailables\Attachment> */
public function attachments(): array
{
return [
Attachment::fromPath('/path/to/invoice.pdf')
->as('invoice-' . $this->invoice->getNumber() . '.pdf')
->withMime('application/pdf'),
];
}
}
{{-- resources/views/emails/invoice.blade.php --}}
<x-mail::message>
# Invoice {{ $invoice->getNumber() }}
Thank you for your order. Here is your invoice summary:
<x-mail::table>
| Item | Amount |
|:-----|-------:|
@foreach ($invoice->getItems() as $item)
| {{ $item->getName() }} | {{ $item->getFormattedAmount() }} |
@endforeach
| **Total** | **{{ $invoice->getFormattedTotal() }}** |
</x-mail::table>
<x-mail::button :url="$url">
View Invoice
</x-mail::button>
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>
// Send immediately
Mail::to($user)->send(new InvoiceMail($invoice));
// Queue for background sending (preferred)
Mail::to($user)->queue(new InvoiceMail($invoice));
// Send later
Mail::to($user)->later(now()->addMinutes(10), new InvoiceMail($invoice));
// Multiple recipients
Mail::to($users)
->cc($manager)
->bcc('archive@example.com')
->send(new InvoiceMail($invoice));
// Assert mail was sent
Mail::fake();
// ... trigger action ...
Mail::assertSent(InvoiceMail::class, function (InvoiceMail $mail) use ($user) {
return $mail->hasTo($user->getEmail());
});
Mail::assertNotSent(InvoiceMail::class);
Mail::assertNothingSent();
Mail::assertQueued(InvoiceMail::class);
// routes/web.php (local only)
Route::get('/mail-preview', function () {
$invoice = Invoice::factory()->create();
return new InvoiceMail($invoice);
});
An email is not a web page. Mail clients strip, rewrite, and ignore CSS that
every browser honors, so a template that renders correctly in
/mail-preview tells you nothing about the inbox. Markdown templates (above)
give you a tested baseline for free — this section is what to hold to when a
design forces you off them.
Four requirements, in order of what breaks first:
<table> elements
with role="presentation", a fixed outer width of 600px, and cellpadding
/ cellspacing / border set to 0. display: flex and
display: grid are unsupported or partially supported in the Windows
Outlook family and collapse to a single stacked column.<style> block. Write style="…" on the element.
A <head><style> block is stripped outright by some webmail clients, and
class selectors then match nothing. Use a CSS inliner at build time if the
template is authored with classes — never ship the classes unresolved. Keep
a <style> block only for what cannot be inlined (media queries), and treat
everything in it as optional.v:fill VML fallback in Outlook, so put the color on
bgcolor and treat the image as decoration.The client list worth testing, and what breaks in each:
| Client | What breaks |
|---|---|
| Outlook 2016-2019 / Windows (Word engine) | flex, grid, float, max-width, border-radius, background images, padding on <div>; the strictest target — if it renders, most others do |
| Outlook.com / Outlook 365 web | strips <style> blocks in some views; rewrites class attributes; ignores margin on several elements |
| Gmail web | clips the message past ~102 KB of HTML with a "view entire message" link — anything below the clip, including the unsubscribe link, is not seen; strips <style> when the message is clipped |
| Gmail app (iOS / Android) | no support for embedded <style> on non-Gmail accounts; media queries ignored there, so the mobile layout must be the fluid default |
| Apple Mail / iOS Mail | the most permissive; auto-scales small text and auto-links dates and addresses unless suppressed — a false green if it is the only client you check |
| Dark mode (Apple Mail, Outlook, Gmail) | colors are force-inverted; a logo on a hardcoded white background becomes a white box on dark, and #000 text on a transparent background becomes invisible |
Verify against a real client, not a preview route. /mail-preview renders in
a browser and proves none of the above. Send to real accounts, or use a
rendering service, before the template ships.
ShouldQueue to avoid blocking requests.build() method.Mail::fake() — verify recipients, content, and queuing.ShouldQueue) — synchronous sending blocks the request.Mail::fake() alone — it doesn't render the template. Use Mail::assertSent() with closure.build() method — use envelope(), content(), attachments().まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.
日本語の概要は準備中です。原文の説明を表示しています。
Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.
日本語の概要は準備中です。原文の説明を表示しています。
Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.
日本語の概要は準備中です。原文の説明を表示しています。
Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.
日本語の概要は準備中です。原文の説明を表示しています。