-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
164 lines (158 loc) · 203 KB
/
Copy pathindex.html
File metadata and controls
164 lines (158 loc) · 203 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-tutorial/Plugins/05-0-upload" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.9.2">
<title data-rh="true">Upload | Agent-first open-source admin panel framework</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" name="twitter:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" property="og:url" content="https://adminforth.dev/docs/tutorial/Plugins/upload/"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Upload | Agent-first open-source admin panel framework"><meta data-rh="true" name="description" content="Guide to the Upload plugin, including storage adapter setup, file and image fields, previews, transformations, and image generation integration."><meta data-rh="true" property="og:description" content="Guide to the Upload plugin, including storage adapter setup, file and image fields, previews, transformations, and image generation integration."><meta data-rh="true" name="twitter:title" content="Upload"><meta data-rh="true" name="twitter:description" content="Guide to the Upload plugin, including storage adapter setup, file and image fields, previews, transformations, and image generation integration."><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://adminforth.dev/docs/tutorial/Plugins/upload/"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/Plugins/upload/" hreflang="en"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/Plugins/upload/" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://VSIPOF54AV-dsn.algolia.net" crossorigin="anonymous"><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"TechArticle","headline":"Upload","description":"Guide to the Upload plugin, including storage adapter setup, file and image fields, previews, transformations, and image generation integration.","url":"https://adminforth.dev/docs/tutorial/Plugins/upload","dateModified":"2026-08-17T05:01:16.000Z"}</script><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Plugins","item":"https://adminforth.dev/docs/tutorial/ListOfPlugins"},{"@type":"ListItem","position":2,"name":"Upload","item":"https://adminforth.dev/docs/tutorial/Plugins/upload"}]}</script><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Agent-first open-source admin panel framework RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Agent-first open-source admin panel framework Atom Feed">
<link rel="preconnect" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7K99Q2BH04"></script>
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-7K99Q2BH04",{anonymize_ip:!0})</script>
<link rel="search" type="application/opensearchdescription+xml" title="Agent-first open-source admin panel framework" href="/opensearch.xml">
<meta name="application-name" content="AdminForth">
<meta name="robots" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="googlebot" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="keywords" content="agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent">
<link rel="image_src" href="https://adminforth.dev/img/adminforth_screenshot.png">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"AdminForth","url":"https://adminforth.dev","description":"Agent-first open-source admin panel framework. Build robust and powerful agentic back-office panels for your projects while maintaining full control over the code.","keywords":"backoffice, vue backoffice, agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent"}</script>
<script src="/scripts/adminforth.js"></script>
<script src="/scripts/tluma-config.js"></script>
<script src="https://tluma.ai/widget.js" async></script><link rel="stylesheet" href="/assets/css/styles.e5bdffa0.css">
<script src="/assets/js/runtime~main.ee0f97d0.js" defer="defer"></script>
<script src="/assets/js/main.a1324122.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<svg style="display: none;"><defs>
<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||"light"),document.documentElement.setAttribute("data-theme-choice",t||"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">AdminForth</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs/tutorial/gettingStarted/">Tutorial</a><a class="navbar__item navbar__link" href="/docs/api/">API</a><a class="navbar__item navbar__link" href="/blog/">Blog</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Live Demo<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/gettingStarted/"><span title="Getting Started" class="linkLabel_WmDU">Getting Started</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item hidden-sidebar"><a class="menu__link" href="/docs/tutorial/hello-world/"><span title="Hello world app without CLI" class="linkLabel_WmDU">Hello world app without CLI</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/glossary/"><span title="Glossary" class="linkLabel_WmDU">Glossary</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Customization/branding/"><span title="Customization" class="categoryLinkLabel_W154">Customization</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/branding/"><span title="Branding and Theming" class="linkLabel_WmDU">Branding and Theming</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customFieldRendering/"><span title="Custom record field rendering" class="linkLabel_WmDU">Custom record field rendering</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/virtualColumns/"><span title="Virtual columns" class="linkLabel_WmDU">Virtual columns</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/hooks/"><span title="Hooks" class="linkLabel_WmDU">Hooks</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/limitingAccess/"><span title="Limiting actions access" class="linkLabel_WmDU">Limiting actions access</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customPages/"><span title="Custom pages" class="linkLabel_WmDU">Custom pages</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/alert/"><span title="Alerts and confirmations" class="linkLabel_WmDU">Alerts and confirmations</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/pageInjections/"><span title="Page Injections" class="linkLabel_WmDU">Page Injections</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/Actions/"><span title="Actions" class="linkLabel_WmDU">Actions</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/menuConfiguration/"><span title="Menu & Header" class="linkLabel_WmDU">Menu & Header</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/dataApi/"><span title="Data API" class="linkLabel_WmDU">Data API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/security/"><span title="Security" class="linkLabel_WmDU">Security</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/standardPagesTuning/"><span title="Standard pages tuning" class="linkLabel_WmDU">Standard pages tuning</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/afcl/"><span title="AdminForth Components Library" class="linkLabel_WmDU">AdminForth Components Library</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/websocket/"><span title="Websocket" class="linkLabel_WmDU">Websocket</span></a></li></ul></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/connectors/"><span title="Connectors" class="linkLabel_WmDU">Connectors</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/deploy/"><span title="Deploy in Docker" class="linkLabel_WmDU">Deploy in Docker</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist" href="/docs/tutorial/ListOfAdapters/"><span title="Adapters" class="categoryLinkLabel_W154">Adapters</span></a><button aria-label="Expand sidebar category 'Adapters'" aria-expanded="false" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/CLICommands/"><span title="CLI Commands" class="linkLabel_WmDU">CLI Commands</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/UsageOfLogger/"><span title="Usage of the logger" class="linkLabel_WmDU">Usage of the logger</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--active" href="/docs/tutorial/ListOfPlugins/"><span title="Plugins" class="categoryLinkLabel_W154">Plugins</span></a><button aria-label="Collapse sidebar category 'Plugins'" aria-expanded="true" type="button" class="clean-btn menu__caret"></button></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/agent/"><span title="Agent" class="linkLabel_WmDU">Agent</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/two-factors-auth/"><span title="Two-Factor Authentication Plugin" class="linkLabel_WmDU">Two-Factor Authentication Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-list/"><span title="Foreign Inline List" class="linkLabel_WmDU">Foreign Inline List</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/audit-log/"><span title="Audit Log" class="linkLabel_WmDU">Audit Log</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/markdown/"><span title="Markdown" class="linkLabel_WmDU">Markdown</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-password-reset/"><span title="Email Password Reset" class="linkLabel_WmDU">Email Password Reset</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/import-export/"><span title="Import Export" class="linkLabel_WmDU">Import Export</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/open-signup/"><span title="Open Signup" class="linkLabel_WmDU">Open Signup</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/i18n/"><span title="Internationalization (i18n)" class="linkLabel_WmDU">Internationalization (i18n)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/oauth/"><span title="OAuth Authentication" class="linkLabel_WmDU">OAuth Authentication</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/inline-create/"><span title="Inline Create" class="linkLabel_WmDU">Inline Create</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/list-in-place-edit/"><span title="List In-Place Edit" class="linkLabel_WmDU">List In-Place Edit</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/text-complete/"><span title="Text Complete" class="linkLabel_WmDU">Text Complete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-show/"><span title="Foreign Inline Show" class="linkLabel_WmDU">Foreign Inline Show</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-invite/"><span title="Email Invite" class="linkLabel_WmDU">Email Invite</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/bulk-ai-flow/"><span title="Bulk AI Flow" class="linkLabel_WmDU">Bulk AI Flow</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/universal-search/"><span title="Universal Search (Legacy)" class="linkLabel_WmDU">Universal Search (Legacy)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/login-captcha/"><span title="Login Captcha" class="linkLabel_WmDU">Login Captcha</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/user-soft-delete/"><span title="User Soft Delete" class="linkLabel_WmDU">User Soft Delete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/clone-row/"><span title="Clone Row" class="linkLabel_WmDU">Clone Row</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/many2many/"><span title="Many to Many" class="linkLabel_WmDU">Many to Many</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/background-jobs/"><span title="Background Jobs" class="linkLabel_WmDU">Background Jobs</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/quick-filters/"><span title="Quick Filters" class="linkLabel_WmDU">Quick Filters</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/auto-remove/"><span title="Auto Remove Plugin" class="linkLabel_WmDU">Auto Remove Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/rich-editor/"><span title="Rich Editor" class="linkLabel_WmDU">Rich Editor</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/CRUDApprove/"><span title="CRUD Approve Plugin" class="linkLabel_WmDU">CRUD Approve Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/json-form/"><span title="JSON Form" class="linkLabel_WmDU">JSON Form</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/docs/tutorial/Plugins/upload/"><span title="Upload" class="linkLabel_WmDU">Upload</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/05-1-upload-api/"><span title="Upload API" class="linkLabel_WmDU">Upload API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard/"><span title="Dashboard plugin" class="linkLabel_WmDU">Dashboard plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard-reference/"><span title="Dashboard Query Reference" class="linkLabel_WmDU">Dashboard Query Reference</span></a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Advanced/plugin-development/"><span title="Advanced" class="categoryLinkLabel_W154">Advanced</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/plugin-development/"><span title="Plugin development guide" class="linkLabel_WmDU">Plugin development guide</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/working-without-direct-database-connection/"><span title="Working without direct database connection" class="linkLabel_WmDU">Working without direct database connection</span></a></li></ul></li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><a class="breadcrumbs__link" href="/docs/tutorial/ListOfPlugins/"><span>Plugins</span></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Upload</span></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Upload</h1></header>
<p>This plugin allows you to upload files to Amazon S3 bucket.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no"></a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">pnpm add @adminforth/upload --save</span><br></span></code></pre></div></div>
<p>Plugin needs some storage adapter to store files and serve them for preview.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-amazon-s3-storage-adapter">Using Amazon S3 storage adapter<a href="#using-amazon-s3-storage-adapter" class="hash-link" aria-label="Direct link to Using Amazon S3 storage adapter" title="Direct link to Using Amazon S3 storage adapter" translate="no"></a></h3>
<p>Amazon S3 is probably the most popular storage service.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">pnpm add @adminforth/storage-adapter-amazon-s3 --save</span><br></span></code></pre></div></div>
<ol>
<li class="">Go to <a href="https://aws.amazon.com" target="_blank" rel="noopener noreferrer" class="">https://aws.amazon.com</a> and login.</li>
<li class="">Go to Services -> S3 and create a bucket. Put in bucket name e.g. <code>my-reality-bucket</code>.
Leave all settings unchanged (ACL Disabled, Block all public access - checked)</li>
<li class="">Go to bucket settings, Permissions, scroll down to Cross-origin resource sharing (CORS) and put in the following configuration:</li>
</ol>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"AllowedHeaders"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"*"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"AllowedMethods"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"HEAD"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"PUT"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"GET"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"AllowedOrigins"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"http://localhost:3500"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"ExposeHeaders"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><br></span></code></pre></div></div>
<blockquote>
<p>☝️ In AllowedOrigins add all your domains. For example if you will serve admin on <code>https://example.com/admin</code> you should add
<code>"https://example.com"</code> to AllowedOrigins:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"https://example.com"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"http://localhost:3500"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><br></span></code></pre></div></div>
<p>Every character matters, so don't forget to add <code>http://</code> or <code>https://</code>!</p>
</blockquote>
<ol start="4">
<li class="">Go to Services -> IAM and create a new user. Put in user name e.g. <code>my-reality-user</code>.</li>
<li class="">Attach existing policies directly -> <code>AmazonS3FullAccess</code>. Go to your user -> <code>Add permissions</code> -> <code>Attach policies directly</code> -> <code>AmazonS3FullAccess</code></li>
<li class="">Go to Security credentials and create a new access key. Save <code>Access key ID</code> and <code>Secret access key</code>.</li>
<li class="">Add credentials in your <code>.env</code> file:</li>
</ol>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">.env</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token constant" style="color:#e6db74">NODE_ENV</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">development </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">your_access_key_id</span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">your_secret_access_key</span><br></span></code></pre></div></div>
<ol start="8">
<li class="">Add credentials in your <code>.env.local</code> file:</li>
</ol>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">.env.local</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token constant" style="color:#e6db74">AWS_REGION</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">your_bucket_region</span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token constant" style="color:#e6db74">AWS_BUCKET_NAME</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">your_bucket_name</span><br></span></code></pre></div></div>
<p>Now add a column for storing the path to the file in the database, add this statement to the <code>./schema.prisma</code>:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">model apartments </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String </span><span class="token decorator at operator" style="color:#66d9ef">@</span><span class="token decorator function" style="color:#e6db74">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> title String </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> square_meter Float</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> price Decimal</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> number_of_rooms Int</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> description String</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> country String</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> listed Boolean</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> realtor_id String</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> apartment_image String</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Migrate prisma schema:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> add-apartment-image </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> migrate:local</span><br></span></code></pre></div></div>
<p>Add column to <code>aparts</code> resource configuration:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/apartments.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> UploadPlugin </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/upload'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForthAdapterS3Storage </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/storage-adapter-amazon-s3'</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> randomUUID </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'crypto'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> admin </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForth</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'aparts'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> all</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> filter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// for create and edit pages plugin put's it's own file dropzone widget, for show and list pages it put's preview</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> plugins</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAdapterS3Storage</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> bucket</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_BUCKET_NAME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> region</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_REGION</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> accessKeyId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> secretAccessKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'jpg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'jpeg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'png'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gif'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webm'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webp'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> maxFileSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">20</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 20 MB</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">originalFilename</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> contentType</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">aparts/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation keyword" style="color:#66d9ef">new</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation class-name" style="color:#e6db74">Date</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation function" style="color:#e6db74">getFullYear</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation function" style="color:#e6db74">randomUUID</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">-</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalFilename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Here you can see how the plugin works:</p>
<p><img decoding="async" loading="lazy" alt="alt text" src="/assets/images/upload_gif-34c98c4dfbe3d08bf7d57af5162ceb5a.gif" width="1889" height="719" class="img_ev3q"></p>
<p>This setup will upload files to S3 bucket with private ACL and save path to file (relative to bucket root) in <code>apartment_image</code> column.</p>
<p>Once you will go to show or list view of <code>aparts</code> resource you will see preview of uploaded file by using presigned temporary URLs
which are generated by plugin:</p>
<p><img decoding="async" loading="lazy" alt="alt text" src="/assets/images/Upload-4597db59b9ee42124ea718716b9e87c3.png" width="3700" height="2800" class="img_ev3q"></p>
<blockquote>
<p>☝ When upload feature is used on record which already exists in database (from 'edit' page), filePath callback will
receive additional parameter <code>record</code> with all values of record. Generally we don't recommend denormalizing any state
of record into s3 path (and instead store links to unique path on s3 in the record field, like in example above).
But if you are 100% sure this kind of sate will be static, you might link to it:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> record</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">game_images/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">record</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">static_game_code</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><br></span></code></pre></div></div>
<p>! Please note that when upload is done from create view, record will be <code>undefined</code>.</p>
</blockquote>
<p>If you want to draw such images in main non-admin app e.g. Nuxt, you should generate presigned URLs by yourself. Here is NodeJS an example of how to do it:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token constant" style="color:#e6db74">AWS</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'aws-sdk'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> s3 </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name constant" style="color:#e6db74">AWS</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">S3</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> accessKeyId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> secretAccessKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> region</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'us-east-1'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">getPresignedUrl</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">s3Path</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">Promise</span><span class="token operator" style="color:#66d9ef"><</span><span class="token builtin" style="color:#e6db74">string</span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> s3</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">getSignedUrlPromise</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'getObject'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> Bucket</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'my-bucket'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> Key</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> s3Path</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> Expires</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">60</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">60</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 1 hour</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Alternatively, if you don't want to generate presigned URLs, you might want to make all objects public. Then you will be able concatenate backet base domain and path stored in db, and use it as source of image. Let's consider how to do it.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="s3-upload-with-public-access">S3 upload with public access<a href="#s3-upload-with-public-access" class="hash-link" aria-label="Direct link to S3 upload with public access" title="Direct link to S3 upload with public access" translate="no"></a></h4>
<ol>
<li class="">First of all go to your bucket settings, Permissions, scroll down to Block public access (bucket settings for this bucket) and uncheck all checkboxes.</li>
<li class="">Go to bucket settings, Permissions, Object ownership and select "ACLs Enabled" and "Bucket owner preferred" radio buttons.</li>
</ol>
<p>Then you can change ACL in plugin configuration:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAdapterS3Storage</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> bucket</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_BUCKET_NAME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> region</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_REGION</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> accessKeyId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> secretAccessKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> s3ACL</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'public-read'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'jpg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'jpeg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'png'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gif'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webm'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webp'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxFileSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">20</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 20 MB</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">originalFilename</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> contentType</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">aparts/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation keyword" style="color:#66d9ef">new</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation class-name" style="color:#e6db74">Date</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation function" style="color:#e6db74">getFullYear</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation function" style="color:#e6db74">randomUUID</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">-</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalFilename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span></code></pre></div></div>
<p>Now every uploaded file will be public so in your custom app you can easily concatenate bucket URL with <code>filePath</code> to get public URL:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">getPublicUrl</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">https://my-bucket.s3.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">region</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.amazonaws.com/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">filePath</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>For preview in AdminForth plugin will still use presigned URLs, but you can change it by providing <code>previewUrl</code> function in plugin configuration:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> preview</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">previewUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">filePath</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">https://my-bucket.s3.us-east-1.amazonaws.com/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">filePath</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<blockquote>
<p>Make sure that you change "my-bucket" and "us-east-1" to your own settings.</p>
</blockquote>
<p>Also you might want to put CDN in front of your bucket, for example <a href="https://developers.cloudflare.com/support/third-party-software/others/configuring-an-amazon-web-services-static-site-to-use-cloudflare/" target="_blank" rel="noopener noreferrer" class="">CloudFlare</a>. In this case
we recommend route all AdminForth previews over CDN as well for faster worm up and better performance.
If for example your domain is <code>my-domain.com</code> and you bucket has name <code>static.my-domain.com</code> you should change preview URL like this:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> preview</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-remove-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">previewUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">filePath</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">https://my-bucket.s3.us-east-1.amazonaws.com/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">filePath</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">previewUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">filePath</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">https://static.my-domain.com/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">filePath</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Also you will have to enable static website hosting in your bucket settings and set index.html and error.html to empty strings.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-local-storage-adapter">Using local storage adapter<a href="#using-local-storage-adapter" class="hash-link" aria-label="Direct link to Using local storage adapter" title="Direct link to Using local storage adapter" translate="no"></a></h3>
<p>The local storage adapter saves files directly on the server’s filesystem and serves them through Express routes. It supports both public and private modes (with presigned URLs).</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">pnpm add @adminforth/storage-adapter-local --save</span><br></span></code></pre></div></div>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> LocalStorageAdapter </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/storage-adapter-local'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">LocalStorageAdapter</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> fileSystemFolder</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"./db/uploads"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adminServeBaseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"static/source"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> mode</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"public"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// or "private"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> signingSecret</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">ADMINFORTH_SECRET</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'jpg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'jpeg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'png'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gif'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webm'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webp'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxFileSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">20</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 20 MB</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">originalFilename</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> contentType</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">aparts/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation keyword" style="color:#66d9ef">new</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation class-name" style="color:#e6db74">Date</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation function" style="color:#e6db74">getFullYear</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation function" style="color:#e6db74">randomUUID</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">-</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalFilename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<blockquote>
<p>adminServeBaseUrl defines the public path prefix. If your AdminForth base URL is /admin, files will be accessible under /admin/static/source/<key>.</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="content-types-and-who-can-upload">Content types and who can upload<a href="#content-types-and-who-can-upload" class="hash-link" aria-label="Direct link to Content types and who can upload" title="Direct link to Content types and who can upload" translate="no"></a></h2>
<p>The content type a file is stored with is derived from its extension on the backend, never taken from the browser. The storage replays that content type when the file is served back, so a client which asks for <code>text/html</code> would be able to store a page that executes scripts on your admin origin with the session of whoever opens it.</p>
<p>The plugin knows the common image, video, audio, document, archive and font extensions. If an extension can't be resolved to a content type, no upload URL is issued, and <code>allowedFileExtensions</code> is validated at startup, so a typo or an unknown extension fails fast:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">Upload plugin can't resolve content type for extension "jpgg". Provide contentTypeByExtension in plugin options</span><br></span></code></pre></div></div>
<p>Use <code>contentTypeByExtension</code> to add extensions the plugin doesn't know, or to override the built-in mapping:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'jpg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'png'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'dwg'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> contentTypeByExtension</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> dwg</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'application/acad'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>Mapping an extension to a content type which browsers execute (<code>text/html</code>, <code>image/svg+xml</code>, <code>application/xhtml+xml</code>, ...) allows anyone who can upload files to run scripts on your admin panel origin with the session of the user who opens the file. Only do it if your storage serves files from a separate origin or with <code>Content-Disposition: attachment</code>.</p></div></div>
<p>Requesting an upload URL requires permission to write the record the file belongs to: <code>edit</code> on the target record when editing an existing one, <code>create</code> otherwise. Users who can only view the resource get <code>403</code> even if they call the API directly, and <code>maxFileSize</code> is enforced on the backend as well, not only in the browser.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="image-generation">Image generation<a href="#image-generation" class="hash-link" aria-label="Direct link to Image generation" title="Direct link to Image generation" translate="no"></a></h2>
<p>Upload plugin supports AI generation for images. Yo use it you need to install image generation adapter.
For example for OpenAI models like <code>gpt-image-1.5</code> (or old <code>DALL-E</code> models):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">add</span><span class="token plain"> @adminforth/image-generation-adapter-openai</span><br></span></code></pre></div></div>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> ImageGenerationAdapterOpenAI </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/image-generation-adapter-openai'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> generation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> countToGenerate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">2</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// how much images generate in one shot</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> adapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">ImageGenerationAdapterOpenAI</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-image-1.5'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> generationPrompt</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Generate image for apartment with title {{title}} and description {{description}}"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> outputSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'1536x1024'</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// size of generated image</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><br></span></code></pre></div></div>
<p>Here is how it works:</p>
<p><img decoding="async" loading="lazy" alt="alt text" src="/assets/images/demoImgGen-1-a819d48d26a84d9a3fd3e288cff7faed.gif" width="1400" height="1050" class="img_ev3q"></p>
<p>You can also pass additional parameters to <a href="https://platform.openai.com/docs/api-reference/images/createEdit" target="_blank" rel="noopener noreferrer" class="">OpenAI API call</a> by using <code>extraParams</code> property:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./apartments.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">ImageGenerationAdapterOpenAI</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-image-1.5'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> extraParams</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> moderation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'low'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> quality</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'high'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> outputSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'1536x1024'</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// size of generated image</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="images-editing-or-post-processing">Images editing or post-processing<a href="#images-editing-or-post-processing" class="hash-link" aria-label="Direct link to Images editing or post-processing" title="Direct link to Images editing or post-processing" translate="no"></a></h2>
<p>You can not only generate images from text, but also edit, post-process or improve existing images. E.g. remove texts, add objects, change colors, etc.</p>
<p>Create a new column <code>apartment_source</code> in <code>apartments</code> table, and put another instance of <code>UploadPlugin</code> in the same resource configuration.</p>
<p>Now tweak the current UploadPlugin configuration in a next way:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./apartments.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">generation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">ImageGenerationAdapterOpenAI</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">attachFiles</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> record</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> record</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">any</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// attach apartment source image to generation, image should be public</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">https://tmpbucket-adminforth.s3.eu-central-1.amazonaws.com/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">record</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">apartment_source</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> generationPrompt</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Remove text from the image"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> countToGenerate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">3</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> outputSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'1024x1024'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p><code>attachFiles</code> function can return an array of URLs to images which will be used as input for image generation.
URLs can be absolute HTTP URLs (should be public in this case) or data-URLs (<code>data:image/png;base64,<base64 content of image></code>).</p>
<p>For example you can use <code>getKeyAsDataURL</code> function from any storage adapter to get image as data-URL:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./apartments.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> StorageAdapter </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">let</span><span class="token plain"> sourceAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> StorageAdapter </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">null</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'source_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'destination_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">plugins</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_source'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">sourcesAdapter </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">LocalStorageAdapter</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> fileSystemFolder</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"./db/uploads"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> mode</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"public"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adminServeBaseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"static/source"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> signingSecret</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">ADMINFORTH_SECRET</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// secret used to generate presigned URLs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> sourcesAdapter</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">LocalStorageAdapter</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> fileSystemFolder</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"./db/uploads"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> mode</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"public"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adminServeBaseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"static/source"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> signingSecret</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">ADMINFORTH_SECRET</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// secret used to generate presigned URLs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> generation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">attachFiles</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> record </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// get picture stored in apartment_source column as data-URL</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain">sourceAdapter</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">getKeyAsDataURL</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">record</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">apartment_source</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> generationPrompt</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Remove text from the image"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> countToGenerate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">3</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> outputSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'1024x1024'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><br></span></code></pre></div></div>
<p>With thus setup you can upload image to <code>apartment_source</code> column, save entity and then generate new image by clicking on <code>Generate</code> button in the <code>apartment_image</code> to remove any text from the image.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="rate-limits">Rate limits<a href="#rate-limits" class="hash-link" aria-label="Direct link to Rate limits" title="Direct link to Rate limits" translate="no"></a></h3>
<p>You can set rate limits for image generation per IP address:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> generation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> rateLimit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> limit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'5/12h'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// up to 5 times per 12 hour </span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> errorMessage</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'You exhausted your image generation limit 5 times per 12 hours, please try again later'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="preview-image-size-configuration">Preview Image Size Configuration<a href="#preview-image-size-configuration" class="hash-link" aria-label="Direct link to Preview Image Size Configuration" title="Direct link to Preview Image Size Configuration" translate="no"></a></h3>
<p>You can set the maximum width for the preview image in the <code>./resources/apartments.ts</code> file by adding the <code>maxWidth</code> property to the <code>preview</code> configuration:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/apartments.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAdapterS3Storage</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> bucket</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_BUCKET_NAME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> region</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_REGION</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> accessKeyId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> secretAccessKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> s3ACL</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"public-read"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'apartment_image'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'jpg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'jpeg'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'png'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gif'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webm'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'webp'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxFileSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">5</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 5MB</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain">originalFilename</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> contentType</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">aparts/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation keyword" style="color:#66d9ef">new</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation class-name" style="color:#e6db74">Date</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation function" style="color:#e6db74">getFullYear</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation function" style="color:#e6db74">randomUUID</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">-</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalFilename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> preview</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Global width settings (applies to all views if specific view settings not provided)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'200px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Maximum width for preview images</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> minWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'200px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Minimum width for preview images</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// List view specific settings</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxListWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'300px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Maximum width in list view</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> minListWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'100px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Minimum width in list view</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Show/detail view specific settings</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxShowWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'200px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Maximum width in show view</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> minShowWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'200px'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Minimum width in show view</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-plugin-for-uploading-avatar">Using plugin for uploading avatar<a href="#using-plugin-for-uploading-avatar" class="hash-link" aria-label="Direct link to Using plugin for uploading avatar" title="Direct link to Using plugin for uploading avatar" translate="no"></a></h2>
<p>Let's say, that you want to use upload plugin for uploading avatar for each user.
To do this add avatar column to the user resource:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model adminuser </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String </span><span class="token decorator at operator" style="color:#66d9ef">@</span><span class="token decorator function" style="color:#e6db74">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> email String </span><span class="token decorator at operator" style="color:#66d9ef">@</span><span class="token decorator function" style="color:#e6db74">unique</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> password_hash String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> role String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> avatar String</span><span class="token operator" style="color:#66d9ef">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Then make migration:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> add-user-avatar-field </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> migrate:local</span><br></span></code></pre></div></div>
<p>Add this column to the users resource:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/adminuser.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"avatar"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">"show"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"edit"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"create"</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">plugins</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">UploadPlugin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> pathColumnName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"avatar"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> storageAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAdapterS3Storage</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> bucket</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_BUCKET_NAME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> region</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_REGION</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> accessKeyId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_ACCESS_KEY_ID</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> secretAccessKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AWS_SECRET_ACCESS_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> allowedFileExtensions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"jpg"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"jpeg"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"png"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"gif"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"webm"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"exe"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"webp"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> maxFileSize</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1024</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">20</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 20MB</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">filePath</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> originalFilename</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> originalExtension</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> contentType</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> record </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">aparts/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation keyword" style="color:#66d9ef">new</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation class-name" style="color:#e6db74">Date</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation function" style="color:#e6db74">getFullYear</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalFilename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">originalExtension</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> preview</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> maxWidth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"200px"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<p>And finally add this callback:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> auth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">avatarUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">adminUser</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">=></span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> plugin </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">getPluginsByClassName</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'UploadPlugin'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">find</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">p </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> p</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">pluginOptions</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">pathColumnName </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'avatar'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">any</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token operator" style="color:#66d9ef">!</span><span class="token plain">plugin</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">Error</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'Upload plugin for avatar not found'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">avatar </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">null</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">||</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">avatar </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">undefined</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">||</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">avatar </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">''</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">undefined</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> imageUrl </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> plugin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">getFileDownloadUrl</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">avatar </span><span class="token operator" style="color:#66d9ef">||</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">''</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">3600</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> imageUrl</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<p>And now you can easily update avatar for each user</p>
<h1>API</h1>
<p>If you wish to reuse Upload plugin for advanced tasks like upload custom files from frontend/backend
(including presigned frontend upload), see <a class="" href="/docs/tutorial/Plugins/05-1-upload-api/">05-1-upload-api.md</a>.</p></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_WFHX"></div><div class="col lastUpdated_JAkA"><span class="theme-last-updated">Last updated<!-- --> on <b><time datetime="2026-08-17T05:01:16.000Z" itemprop="dateModified">Aug 17, 2026</time></b></span></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/tutorial/Plugins/json-form/"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">JSON Form</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/tutorial/Plugins/05-1-upload-api/"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Upload API</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#installation" class="table-of-contents__link toc-highlight">Installation</a><ul><li><a href="#using-amazon-s3-storage-adapter" class="table-of-contents__link toc-highlight">Using Amazon S3 storage adapter</a></li><li><a href="#using-local-storage-adapter" class="table-of-contents__link toc-highlight">Using local storage adapter</a></li></ul></li><li><a href="#content-types-and-who-can-upload" class="table-of-contents__link toc-highlight">Content types and who can upload</a></li><li><a href="#image-generation" class="table-of-contents__link toc-highlight">Image generation</a></li><li><a href="#images-editing-or-post-processing" class="table-of-contents__link toc-highlight">Images editing or post-processing</a><ul><li><a href="#rate-limits" class="table-of-contents__link toc-highlight">Rate limits</a></li><li><a href="#preview-image-size-configuration" class="table-of-contents__link toc-highlight">Preview Image Size Configuration</a></li></ul></li><li><a href="#using-plugin-for-uploading-avatar" class="table-of-contents__link toc-highlight">Using plugin for uploading avatar</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/docs/tutorial/gettingStarted/">Tutorial</a></li><li class="footer__item"><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Live Demo</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/api/">API</a></li><li class="footer__item"><a class="footer__link-item" href="/blog/archive/">Blog Archive</a></li><li class="footer__item"><a class="footer__link-item" href="/search/">Find anything</a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://devforth.io" target="_blank" rel="noopener noreferrer" class="footer__link-item">DevForth.io<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://devforth.io/contact" target="_blank" rel="noopener noreferrer" class="footer__link-item">We can develop admin panel for your project<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2026 Devforth sp. z o.o.</div></div></div></footer></div>
</body>
</html>