使用Symfony与Webpack Encore时,通过绝对URL无法访问邮件模板中的图片
Let's break down what's going wrong and fix this step by step. The core issue here is twofold: your Webpack Encore setup might not be copying images to the right accessible location, and relying on localhost-hosted external images for emails can be fragile (even for local testing). Here's how to resolve both:
1. Fix Webpack Encore Asset Copying for Email Images
Looking at your webpack.config.js, your existing copyFiles rule handles page-specific images, but let's adjust it to ensure email-specific assets are always accessible outside your build's entry-point tied resources.
First, create a dedicated folder in assets for email images (e.g., assets/email-images) to keep them separate from regular page assets. Then add a new copyFiles rule to copy these directly to the root of your public directory (not inside build, which can be affected by versioning or entry point cleanup):
// Add this alongside your existing copyFiles rule .copyFiles({ from: './assets/email-images', // Output to public/email-images (since setOutputPath is public/build, ../ moves up one level) to: '../email-images/[path][name].[ext]' })
Critical Note: After modifying webpack.config.js, you must restart npm run watch (stop it with Ctrl+C and rerun the command) — Encore doesn't pick up config changes on the fly.
2. Verify Assets Are Copied Correctly
Check your public/email-images folder — you should see your my-image.png there. If not:
- Double-check the
frompath in your newcopyFilesrule (make sure it matches where you stored the image inassets). - Look for errors in your
npm run watchoutput (Webpack will log if it can't find source files). - In WSL2, ensure file permissions are correct: sometimes files added from Windows need to be copied within WSL or have permissions adjusted (
chmod 644 public/email-images/my-image.png) to be accessible.
3. Update Your Twig Template Path
Now use the correct asset path in your Twig file. Since images are in public/email-images, the asset reference will be email-images/my-image.png:
<img src="{{ absolute_url(asset('email-images/my-image.png')) }}" alt="My Image">
Test this by visiting https://localhost:8000/email-images/my-image.png directly — you should see the image load. Resend the email via your EmailController and check MailHog again.
4. (Better Alternative) Embed Images Directly in the Email
Even if you fix localhost access, most email clients block external images by default. A more reliable approach is to embed the image directly into the email body. Here's how to do it with Symfony Mailer:
In your EmailController:
use Symfony\Bridge\Twig\Mime\TemplatedEmail; // ... public function sendEmail() { $projectDir = $this->getParameter('kernel.project_dir'); $imagePath = $projectDir . '/public/email-images/my-image.png'; $email = (new TemplatedEmail()) ->from('your@example.com') ->to('recipient@example.com') ->subject('Test Email with Embedded Image') ->htmlTemplate('email/test.html.twig') // Embed the image and assign it a reusable name "my-image" ->embed(fopen($imagePath, 'r'), 'my-image'); $this->mailer->send($email); // ... }
Then reference the embedded image in your Twig template using the assigned name:
<img src="{{ email.image('my-image') }}" alt="My Image">
This way, the image is included directly in the email, so it will display without relying on external URLs (even if localhost isn't accessible to the email client).
Quick Troubleshooting Checks
- If images still break, clear your Symfony cache with
php bin/console cache:clearto ensure the asset helper uses the latest paths. - Confirm your Symfony server is binding to
0.0.0.0(Symfony'sserver:startdoes this by default, but verify withphp bin/console server:status).
内容的提问来源于stack exchange,提问作者Lushawn

