25

I have just upgraded my 5.2 install of laravel to 5.3 and then to 5.4 following the official upgrading methods.

I am now trying to use one of the new features, to create a markdown formated email.

According to the documentation found at: https://laravel.com/docs/5.4/mail#view-data

To embed an inline image, use the embed method on the $message variable within your email template. Laravel automatically makes the $message variable available to all of your email templates, so you don't need to worry about passing it in manually:

However, this:

<img src="{{ $message->embed(public_path().'/img/official_logo.png') }}">

will produce the following error:

Undefined variable: message

Am I missing something? Or is there something undocumented in the upgrading guides?

Later edit:

I am calling the email function with:

\Mail::to($user)->send(new WelcomeCandidate($user, $request->input('password')));

And WelcomeCandidate looks like:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\Models\User;

class WelcomeCandidate extends Mailable
{

    use Queueable, SerializesModels;

    public $user;
    public $password;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(User $user, $password)
    {
        //
        $this->user = $user;
        $this->password = $password;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $this->subject('Welcome!');
        return $this->markdown('emails.welcome-candidate');
    }
}
Angelin Calu
  • 1,905
  • 8
  • 24
  • 44
  • show some more code, but what the error is saying is pretty clear. You didn't define the message variable on your mailable class or your notification class or you didn't assign any value to it in the constructor of your mailable / notification. Also if you gonna use markdown, you don't need the image tag. – Christophvh Feb 28 '17 at 08:29
  • I did it according instructions, as you can see in the quoted text. What code should I provide? – Angelin Calu Feb 28 '17 at 08:33
  • the code where you exectute your mailable class: so for example : `$message = "hello"; Mail::to($request->user())->send(new OrderShipped($message));` – Christophvh Feb 28 '17 at 08:44
  • I have added the code in the question. – Angelin Calu Feb 28 '17 at 08:49
  • Same issue was raised here: https://github.com/laravel/framework/issues/17629 . No solutions though. – Angelin Calu Feb 28 '17 at 08:56

9 Answers9

26

It seems that the older $message->embed doesn't work nicely with Markdown emails. Like you mentioned in the comments it seems broken since 5.4

But you could just try it like this inside your markdown email:

This is your logo 
![Some option text][logo]

[logo]: {{asset('/img/official_logo.png')}} "Logo"

Like shown here: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#images

Asset function reference: https://laravel.com/docs/5.4/helpers#method-asset

Angelin Calu
  • 1,905
  • 8
  • 24
  • 44
Christophvh
  • 12,586
  • 7
  • 48
  • 70
15

Try this:

<img src="data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}}" alt="">

or

![](data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}})
Mikael M
  • 1,375
  • 14
  • 14
  • I like this solution but no dice unfortunately. – Benco Jan 28 '18 at 00:25
  • As much as I love serialized image data mega pasted into an image tag... they are specifically unwelcome on many email services and clients. I love base64 encoded images for certain purposes, don't get me wrong. It is just email is not one of those things specifically for the non-display of images and outright failure to accomplish the single purpose of presenting a visible image. It is the back half of 2018, we'll see how well this comment ages. Maybe it will be less true in a few years... – BradChesney79 Oct 02 '18 at 13:23
  • 3
    This will cause issues on services such as Gmail where extremely long lines of HTML are force-wrapped at ~10,240 characters; If your image is > 8KB, it'll have spaces inserted into the base64-encoded string, breaking it - `` – amphetamachine Apr 30 '19 at 22:30
6

Solved my issue!

  <img src="{{ $message->embed(base_path() . '/img/logo.png') }}" />
Controller:


\Mail::send(['html' =>'mail'],
        array(
            'name' => $r->name,
            'email' => $r->email,
            'user_message' => $r->message,
           // 'telephone'=>$r->telephone,
           // 'subject'=>$r->subject
        ), function($message) use ($r)  {

            $message->to('abc@gmail.com')->subject('Contact Form || abc.com');
            $message->from($r->email);
            // ->setBody($r->user_message); // assuming text/plain

        });

If you are in localhost , you can use public_path instead of base_path function

Nur Uddin
  • 1,798
  • 1
  • 28
  • 38
5

You can also use this useful package

https://github.com/eduardokum/laravel-mail-auto-embed

Taken from the readme

Its use is very simple, you write your markdown normally:

@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Purchased product:

![product](https://example.com/products/product-1.png)

Thanks,<br>
{{ config('app.name') }}
@endcomponent

When sending, it will replace the link that would normally be generated:

<img src="https://example.com/products/product-1.png">

by an embedded inline attachment of the image:

<img src="cid:3991f143cf1a86257f8671883736613c@Swift.generated">
cyberfly
  • 5,568
  • 8
  • 50
  • 67
3

I just encountered the same issue and found a solution.

Before rendering images you have to create a symbolic link from "public/storage" to "storage/app/public" using this command:

php artisan storage:link

In "storage/app/public" you should have a folder "images" Now you can render this code in your markdown.blade.php:

!['alt_tag']({{Storage::url('/images/your_image.png')}})

Second option is similar:

!['alt_text']({{Storage::url($comment->user->image->path)}}) 

Both work fine

robrok
  • 47
  • 4
0

You could try the following:

class WelcomeCandidate extends Mailable
{
    use Queueable, SerializesModels;

    public $message;
    public function __construct(User $user)
    {
        $this->user = $user;
        $this->message = (object) array('image' => '/path/to/file');
    }
}
TrampolineTales
  • 808
  • 3
  • 14
  • 31
0

The below solution works for me.

<img src="{{ $message->embed(asset('img/logo.png')) }}"/>

In .env file.

For local: APP_URL=http://localhost/project_name

For Production: APP_URL=https://www.example.com

Reference: https://laravel.com/docs/7.x/mail#inline-attachments

Soubhagya Kumar Barik
  • 1,979
  • 20
  • 26
0

Laravel supports the embed method in all laravel versions, 7, 8, 9, and 10. How do embed images in laravel?

<img src="{{ $message->embed($pathToImage) }}">

Laravel automatically makes the $message variable available to all of your email templates, so you don't need to worry about passing it in manually:

Hadayat Niazi
  • 1,991
  • 3
  • 16
  • 28
-1

In backend i created endpoint for showing images. And put image that i need in resource/img. Laravel code looks like:

 public function getImage($name)
 {
        return response()->file(base_path() . '/resources/img/' . $name . '.png');
 }

Then in my html email template i created div with background-image.

<div style='background: url("https://mysite1.com/api/v1/get_image/logo")'></div>

And it's works for me.

Maxim Paladi
  • 91
  • 1
  • 7