Create a brick
Use the File component
Let editors upload a file and render a download link using the React Bricks File component.
What you'll build
In this how-to, you'll create a CatalogDownload brick using the React Bricks <File> component.
This is useful when editors need to upload downloadable assets like:
- PDFs
- catalogs
- brochures
- documents
- short videos
At the end, editors will be able to upload a file in the admin, and your brick will render a download link on the page.
Create a new brick
Create a new CatalogDownload.tsx file and start with this code:
import { File, types } from 'react-bricks/rsc'
interface CatalogDownloadProps {
file: types.IFileSource
}
const CatalogDownload: types.Brick<CatalogDownloadProps> = ({ file }) => {
return (
<div>
<File
propName="file"
source={file}
allowedExtensions={['.pdf']}
renderBlock={(file) => {
return file ? (
<a
href={file.url}
className="flex h-full items-center font-semibold"
>
Download "{file.name}" <small>({file.size.toFixed(2)} MB)</small>
</a>
) : (
<div className="flex h-full items-center font-semibold">
No catalogs yet.
</div>
)
}}
/>
</div>
)
}
CatalogDownload.schema = {
name: 'catalog-download',
label: 'Catalog Download',
}
export default CatalogDownloadIf you're using Next.js App Router, import File from react-bricks/rsc.
If you're using Astro, import it from react-bricks/astro.
Add the file prop
The component interface uses:
file: types.IFileSourcetypes.IFileSource is the React Bricks type for a visually editable file field.
This prop will contain the uploaded file data.
Use the <File> component
Inside the brick, we render:
<File
propName="file"
source={file}
allowedExtensions={['.pdf']}
renderBlock={(file) => {
return file ? (
<a href={file.url} className="flex h-full items-center font-semibold">
Download "{file.name}" <small>({file.size.toFixed(2)} MB)</small>
</a>
) : (
<div className="flex h-full items-center font-semibold">
No catalogs yet.
</div>
)
}}
/>Here is what the main props do:
propName="file"binds the field to thefilepropsource={file}passes the current file valueallowedExtensions={['.pdf']}limits uploads to PDF filesrenderBlockdefines how the uploaded file should be rendered
How renderBlock works
The renderBlock function receives the uploaded file as its argument.
If a file is available, you can use its data to render custom UI.
In this example we use:
file.urlfor the download linkfile.namefor the file namefile.sizefor the size in MB
That is why the code checks:
file ? (...) : (...)When a file exists, we render a download link. When there is no file yet, we render a placeholder message.
Why allowedExtensions is useful
allowedExtensions helps restrict the kinds of files editors can upload.
For example:
['.pdf']only allows PDF files['.pdf', '.docx']would allow both PDFs and Word documents
This is useful when the brick is meant for a very specific file type.
Final code
Your full CatalogDownload.tsx file should look like this:
import { File, types } from 'react-bricks/rsc'
interface CatalogDownloadProps {
file: types.IFileSource
}
const CatalogDownload: types.Brick<CatalogDownloadProps> = ({ file }) => {
return (
<div>
<File
propName="file"
source={file}
allowedExtensions={['.pdf']}
renderBlock={(file) => {
return file ? (
<a
href={file.url}
className="flex h-full items-center font-semibold"
>
Download "{file.name}" <small>({file.size.toFixed(2)} MB)</small>
</a>
) : (
<div className="flex h-full items-center font-semibold">
No catalogs yet.
</div>
)
}}
/>
</div>
)
}
CatalogDownload.schema = {
name: 'catalog-download',
label: 'Catalog Download',
}
export default CatalogDownloadDefault files
If you want, you can also provide a default file using getDefaultProps in the schema.
That can be useful if you already have a standard catalog or document you want new brick instances to start with.