@oliverbutler, thanks for the solution. It worked for me. That said, you should really include all packages installed and all files touched to implement your solution. As is, the tutorial’s incomplete.
If you don’t mind, can you please guide a littler further on what packages & files needed beside the tutorial? I am also trying to implement it in my project.
hey @oliverbutler - your link is dead now, but I just came across this thread. We are using next/image and having a blurhash coming directly from strapi would be amazing!
To configure blur hash for v4 you can do as follows:
By the using the register function in ./src/index.js do an extension the content type and redefine the default function ‘uploadFileAndPersist’ with blur hash logic.
Add the following:
Hi everyone, based on Nikita_Ostryakov answer there’s a slightly easier way:
We are leveraging https://plaiceholder.co to make our base64 (or any other type of placeholder type). To install this run npm install plaiceholder or yarn add plaiceholder
Make a file inside the ./src/extensions folder named extendFileUpload.js. Put the following code inside the file (I chose to have a separate file for the extension to keep things clean):
// ./src/extensions/extendFileUpload.js
const plaiceholder = require('plaiceholder');
const _ = require('lodash');
module.exports = {
generatePlaceholder(strapi) {
// Here we are adding the attribute 'placeholder' to the file types
strapi.contentType('plugin::upload.file').attributes.placeholder = {
type: 'string',
};
strapi.plugin('upload').services.upload.uploadFileAndPersist =
async function (fileData, { user } = {}) {
const config = strapi.config.get('plugin.upload');
const {
getDimensions,
generateThumbnail,
generateResponsiveFormats,
} = strapi.plugin('upload').service('image-manipulation');
await strapi.plugin('upload').provider.upload(fileData);
const thumbnailFile = await generateThumbnail(fileData);
if (thumbnailFile) {
await strapi
.plugin('upload')
.provider.upload(thumbnailFile);
// Here we are generating the placeholder based on the thumbnail buffer
try {
await plaiceholder
.getPlaiceholder(thumbnailFile.buffer)
.then(({ base64 }) => {
// We'll set the generated base64 string to your placeholder attribute
fileData.placeholder = base64;
});
} catch (error) {
console.log(error);
error;
}
delete thumbnailFile.buffer;
_.set(fileData, 'formats.thumbnail', thumbnailFile);
}
const formats = await generateResponsiveFormats(fileData);
if (Array.isArray(formats) && formats.length > 0) {
for (const format of formats) {
if (!format) continue;
const { key, file } = format;
await strapi.plugin('upload').provider.upload(file);
delete file.buffer;
_.set(fileData, ['formats', key], file);
}
}
const { width, height } = await getDimensions(fileData.buffer);
delete fileData.buffer;
_.assign(fileData, {
provider: config.provider,
width,
height,
});
return this.add(fileData, { user });
};
},
};
Open the ./src/index.js where you add the following:
When you upload a new image, the placeholder will be generated as well. When you fetch your images a new attribute will be populated, namely the placeholder attribute.
(bonus) If you are using Next.js, you can use the placeholder="blur" and blurDataURL={placeholder} attributes to make your image utilise the placeholder we just created.