What seems to be the problem:
Temporary images display locally, but not on live site. The images still upload, but are not displaying on-screen as intended. The previews look like they load, but nothing is displayed. I can see the blank image blocks in the preview area, along with each’s signed URL.
Console shows 404 errors for each image uploaded. Attempting to load the signed URL in a different tab results in a 401.
I’m unsure if this is intended or my issue, or how to correct if it is, or if it something else.
Any and all help appreciated. Cheers!
Steps to Reproduce:
Upload an image(s) on live server.
Are you using the latest version of Livewire:
“livewire/livewire”: “^2.0”,
Do you have any screenshots or code examples:
VIEW
<div class="w-full" x-data="{ progress: 0, isUploading: false }"
x-on:livewire-upload-start="isUploading = true"
x-on:livewire-upload-finish="isUploading = false"
x-on:livewire-upload-error="isUploading = false"
x-on:livewire-upload-progress="progress = $event.detail.progress">
<label class="flex-col mb-2 text-sm font-bold text-gray-700" for="images">
<div class="flex flex-row flex-no-wrap w-full h-16 sm:h-20 md:h-24 bg-gray-200 focus:outline-none cursor-pointer items-center text-center rounded border @error('images') border-red-600 @else border-gray-200 @enderror overflow-y-hidden overflow-x-scroll mb-3">
@if( ! empty( $images ) )
@foreach( $images as $image )
@php
$load = false;
$ext = ['jpg','jpeg','png','webp','heic','heif'];
if ( in_array( $image->guessExtension() , $ext ) ) {
$load = true;
}
@endphp
@if($load)
<div class="flex-none h-16 bg-no-repeat bg-center bg-cover mr-2 {{ $loop->first ? 'ml-4' : '' }}" style="background-image: url({{ $image->temporaryUrl() ?? '' }}); width: 100px;"></div>
@else
<div class="block w-16">
<span class="text-sm text-red-600">
<span class="uppercase">{{ $image->guessExtension() }}</span> is an invalid filetype. An image is required.
</span>
</div>
@endif
@endforeach
@else
<div class="block w-full">
<span class="w-full self-center mx-auto @error('images') text-red-600 @else text-gray-700 @enderror text-gray-700 font-bold">Upload Image</span>
@error('images')
<p class="w-full text-red-500 mt-1 text-sm font-normal pb-2 hidden md:block">{{ $message }}</p>
@enderror
</div>
@endif
</div>
<input wire:model="images" class="w-full px-3 py-2 text-base leading-tight border border-gray-200 bg-gray-200 focus:bg-white text-gray-700 rounded shadow appearance-none hidden"
id="images" name="images" type="file" multiple />
</label>
<div wire:loading wire:target="images" class="w-full my-2 text-red-600 text-center font-bold">Uploading...</div>
</div>
CONTROLLER
namespace App\Http\Livewire;
use Image;
use Storage;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Validation\ValidationException;
class XXXXX extends Component
{
use WithFileUploads;
public $images = [];
public $imageList = [];
[...]
public function goToStepThree()
{
if( empty( $this->images ) ) {
throw ValidationException::withMessages( ['images' => 'At least one image is required.'] );
}
// Get rid of any old images
if( count( $this->imageList ) > 0 ) {
foreach( $this->imageList as $oldImage ) {
Storage::delete( $oldImage );
}
$this->reset( 'imageList' );
}
// Resize and store each image
foreach( $this->images as $image ) {
$this->resizeAndStoreTheImage( $image );
}
[...]
}
protected function resizeAndStoreTheImage( $image )
{
// Set the new image's name
$filename = time() . '-' . mt_rand( 10000 , 1000000 );
$filename_w_ext = $filename . '.' . $image->extension();
// Save original uploaded image
$original_image = $image->storeAs( 'ticket-request-images' , $filename_w_ext );
// Get the original uploaded image's details
list( $original_image_width,
$original_image_height,
$original_image_type,
$original_image_attr
) = getimagesize( Storage::path( $original_image ) );
// Define new sizes
$newSizes = [
'xs' => [
'size' => 250,
'quality' => 60
],
'md' => [
'size' => 600,
'quality' => 70
],
'lg' => [
'size' => 1024,
'quality' => 80
],
'xl' => [
'size' => 2048,
'quality' => 90
],
];
$thumbs = [];
while( $this_new_size = current( $newSizes ) ) {
// Get the size key, i.e. 'xs','md','lg'...
$key = key( $newSizes );
// Create a dynamic variable for folder path
${$key} = Image::make( Storage::path( $original_image ) );
// If the height or width of image is greater than newSizes size
if( $original_image_width > $this_new_size['size'] || $original_image_height > $this_new_size['size'] ) {
// Resize images - constrain to the new size's size on either side
${$key}->resize( $this_new_size['size'] , $this_new_size['size'] , function ($constraint){
$constraint->aspectRatio();
})->stream( 'jpeg' , $this_new_size['quality'] );
// Set the location
$location = 'ticket-request-images/thumbnails/' . $key . '/' . $filename . '.jpg';
// Store the resized image
Storage::put( $location , ${$key} );
// Push the location to the thumbs array
array_push( $thumbs , $location );
}
next($newSizes);
}
// Add the location to the imageList array
array_push( $this->imageList, $thumbs );
// Delete original, non-resized image
Storage::delete( $original_image );
}