Compare commits
2464 Commits
db-postgre
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25968d43c2 | ||
|
|
9e76c8f4e3 | ||
|
|
3b3b1cecc5 | ||
|
|
6862b43261 | ||
|
|
a3e1856bde | ||
|
|
6612bd1c98 | ||
|
|
ce2ae9561d | ||
|
|
1a03e9ace5 | ||
|
|
e7159c033e | ||
|
|
628749573e | ||
|
|
0920c8a2f0 | ||
|
|
680ed1dec8 | ||
|
|
ddc3ab534e | ||
|
|
7c35e8865c | ||
|
|
8f6cedf67a | ||
|
|
7bb2e3be76 | ||
|
|
78db50a497 | ||
|
|
f36bf5e4e3 | ||
|
|
d10792452f | ||
|
|
c500ac83b2 | ||
|
|
082650c0e2 | ||
|
|
11de4b037d | ||
|
|
0162560996 | ||
|
|
ed0820f6c8 | ||
|
|
e148243260 | ||
|
|
8e56328e63 | ||
|
|
019677b7e6 | ||
|
|
0d31021c25 | ||
|
|
8e9ed2ebe3 | ||
|
|
763a34f19b | ||
|
|
be0462db56 | ||
|
|
6e55a2e52d | ||
|
|
4e127054ca | ||
|
|
27510bb963 | ||
|
|
de45e6094b | ||
|
|
74159de1ec | ||
|
|
ba92d864bb | ||
|
|
0fb14cfebe | ||
|
|
2ada6fc58d | ||
|
|
cb3355b30f | ||
|
|
10c6ffafc3 | ||
|
|
6512d5ce69 | ||
|
|
57fcc9148e | ||
|
|
36f4f23463 | ||
|
|
7b7dc71845 | ||
|
|
ba513d5a97 | ||
|
|
a26d03190e | ||
|
|
9f525621c8 | ||
|
|
7309d474ee | ||
|
|
45e86832c2 | ||
|
|
1bd91b23ca | ||
|
|
ac34380eb8 | ||
|
|
17707852e0 | ||
|
|
8b95218577 | ||
|
|
a79d23c631 | ||
|
|
52c81ad525 | ||
|
|
8ec836737e | ||
|
|
e4a90294ea | ||
|
|
7c8d562f03 | ||
|
|
11c3a65e63 | ||
|
|
8dd5e4dc24 | ||
|
|
9bd9e7a986 | ||
|
|
66e00f8172 | ||
|
|
b95e25e937 | ||
|
|
5722c530a1 | ||
|
|
267c23616d | ||
|
|
19f8cbcf76 | ||
|
|
aee3ee21d1 | ||
|
|
ff82bb5661 | ||
|
|
8a78134b72 | ||
|
|
1dbb29e847 | ||
|
|
2077da8665 | ||
|
|
b2751f75d5 | ||
|
|
1afd221795 | ||
|
|
aeb4df894a | ||
|
|
f91c19e1fd | ||
|
|
bcd277eaaa | ||
|
|
da35afbd8f | ||
|
|
cafc13a7d5 | ||
|
|
2b6bff3c1d | ||
|
|
95f499d2bd | ||
|
|
6659fd1b97 | ||
|
|
45b02d8827 | ||
|
|
59cde0dbb3 | ||
|
|
1aece399f7 | ||
|
|
c3589ded08 | ||
|
|
c7fbd76dae | ||
|
|
6b9c796218 | ||
|
|
5cb49c3307 | ||
|
|
f41bb05c70 | ||
|
|
c68189788c | ||
|
|
e603c83f55 | ||
|
|
edfa85bcd5 | ||
|
|
b86d4c647f | ||
|
|
4884f0d297 | ||
|
|
f1db24e303 | ||
|
|
7f15147286 | ||
|
|
e0a6db7f97 | ||
|
|
0d7d3e5c92 | ||
|
|
8b49402e4c | ||
|
|
347464250e | ||
|
|
aa02801c3d | ||
|
|
a3ee07f693 | ||
|
|
511908a964 | ||
|
|
425576be25 | ||
|
|
92f458dad2 | ||
|
|
043a91d719 | ||
|
|
54e2d7fb38 | ||
|
|
321e97f9fe | ||
|
|
4e0dfd410d | ||
|
|
8506385ef9 | ||
|
|
e74952902e | ||
|
|
4a51f4d2c1 | ||
|
|
2c283bcc08 | ||
|
|
a2e9bcd333 | ||
|
|
33d53121a2 | ||
|
|
e0b201c810 | ||
|
|
a8000f644f | ||
|
|
7d0e909a30 | ||
|
|
b2662eeb1f | ||
|
|
0b274dd67e | ||
|
|
2ddd50edc4 | ||
|
|
0287acb8f0 | ||
|
|
10c94b3665 | ||
|
|
ea48ca377e | ||
|
|
6f5d86ed84 | ||
|
|
c383f391e3 | ||
|
|
8a91a7adbb | ||
|
|
96181d91a6 | ||
|
|
eff5129a5f | ||
|
|
38e5adc462 | ||
|
|
ff4ea1eecc | ||
|
|
dbfd1beed5 | ||
|
|
4b6774463e | ||
|
|
cb14b97a6e | ||
|
|
18bc4b708c | ||
|
|
6d951e6987 | ||
|
|
365660764d | ||
|
|
8b91af8a5b | ||
|
|
b4092f59ae | ||
|
|
7a768144ea | ||
|
|
3839eb5ab0 | ||
|
|
fd02bee0fe | ||
|
|
42222cd2f6 | ||
|
|
e3222f2ac3 | ||
|
|
35f961fecb | ||
|
|
85bfca79ef | ||
|
|
661a4a099d | ||
|
|
72c0534008 | ||
|
|
78579ed2bd | ||
|
|
7bcb4ba1cc | ||
|
|
6b45cf3197 | ||
|
|
73d0b209d7 | ||
|
|
c93752bdbb | ||
|
|
7a4dd5890e | ||
|
|
60ee55fcaa | ||
|
|
1fe9790d0d | ||
|
|
3c0853a675 | ||
|
|
2b941b7e2c | ||
|
|
db772a058c | ||
|
|
0bfbf9c750 | ||
|
|
5c7647f45b | ||
|
|
6c952875e8 | ||
|
|
af7e12aa2f | ||
|
|
bcc506b423 | ||
|
|
3d7c8277d7 | ||
|
|
a8a2dc2347 | ||
|
|
6c74b0326b | ||
|
|
f51af92491 | ||
|
|
77528a1e7d | ||
|
|
ba8b8e8330 | ||
|
|
23f9a32a99 | ||
|
|
0190eb8b28 | ||
|
|
f482fdcfd5 | ||
|
|
ed4766188d | ||
|
|
e682cb1b04 | ||
|
|
36fda30c61 | ||
|
|
fa7cc376d1 | ||
|
|
3fc2ff1ef9 | ||
|
|
1d81eef805 | ||
|
|
8fcfac61b5 | ||
|
|
0d544dacdb | ||
|
|
147b50e719 | ||
|
|
eeb689dd55 | ||
|
|
c2571cfdb6 | ||
|
|
12c812d379 | ||
|
|
bf106db6e2 | ||
|
|
18009349c0 | ||
|
|
89b6055d61 | ||
|
|
d9a8869132 | ||
|
|
9d5c0d350c | ||
|
|
4dedd6e267 | ||
|
|
276213193b | ||
|
|
553bb4b530 | ||
|
|
5083525189 | ||
|
|
e4185259b4 | ||
|
|
5323d76a5b | ||
|
|
608387084c | ||
|
|
9556d1bd42 | ||
|
|
a6bf05815c | ||
|
|
a4deaf07d6 | ||
|
|
4adf01ab04 | ||
|
|
1abcdf96fa | ||
|
|
3456b5f6a7 | ||
|
|
d053778bf2 | ||
|
|
fbad39a120 | ||
|
|
e8d1d369cf | ||
|
|
fbea52416c | ||
|
|
cb9a20fefa | ||
|
|
8db9664700 | ||
|
|
08add653c7 | ||
|
|
eed9676536 | ||
|
|
22480a7648 | ||
|
|
aa2073f9e9 | ||
|
|
e0618f81a5 | ||
|
|
ea90018979 | ||
|
|
5a4074e90a | ||
|
|
0e9bbecbee | ||
|
|
c8a1ccaf4b | ||
|
|
79f4907cb3 | ||
|
|
6a0fffe002 | ||
|
|
6e116a76fd | ||
|
|
f52607f3b5 | ||
|
|
f716122eab | ||
|
|
353c2b0be2 | ||
|
|
58bbbbd395 | ||
|
|
57b072edfc | ||
|
|
f6039246c6 | ||
|
|
fcee13b017 | ||
|
|
ef5197a514 | ||
|
|
7438812db3 | ||
|
|
48af78278d | ||
|
|
3abc2e8328 | ||
|
|
a48043c2aa | ||
|
|
7e4f50a01c | ||
|
|
40d3078bf2 | ||
|
|
662334abfb | ||
|
|
aa5ad47177 | ||
|
|
890c21dda4 | ||
|
|
c7635b2783 | ||
|
|
47cd5f4d01 | ||
|
|
0d98b4b96f | ||
|
|
a20cf70105 | ||
|
|
23c7ab2bc4 | ||
|
|
0680e0c58b | ||
|
|
b3df253880 | ||
|
|
a78b44d0c1 | ||
|
|
d272a1fd22 | ||
|
|
095e4402ac | ||
|
|
60d2def428 | ||
|
|
2f02b3a6e1 | ||
|
|
0886e4e972 | ||
|
|
4f0ddcf632 | ||
|
|
693621a6e3 | ||
|
|
5b201392cc | ||
|
|
a70bcf81c0 | ||
|
|
ed880d5018 | ||
|
|
ea84e82ad5 | ||
|
|
4216d69ccb | ||
|
|
550a40d6a2 | ||
|
|
dcad5003f5 | ||
|
|
bd9c06a99d | ||
|
|
48932ef54d | ||
|
|
261f6dc20d | ||
|
|
4aeefc5a1a | ||
|
|
e96ff90029 | ||
|
|
f6e77b845b | ||
|
|
a0bb02d05a | ||
|
|
354ad7092c | ||
|
|
f9d862d854 | ||
|
|
f41576dd65 | ||
|
|
ffa20aa7d0 | ||
|
|
f7a2cf96b9 | ||
|
|
cfeac79b99 | ||
|
|
821bed0ea6 | ||
|
|
1a20390454 | ||
|
|
9e9111666b | ||
|
|
5065322d31 | ||
|
|
ad4796cdb2 | ||
|
|
43b7ba82da | ||
|
|
3785c79ac9 | ||
|
|
4384e9eb0e | ||
|
|
9364f8da2e | ||
|
|
a4ef359660 | ||
|
|
848c05f247 | ||
|
|
ec556360b6 | ||
|
|
d99b426e3b | ||
|
|
19a78297b4 | ||
|
|
e95eea694c | ||
|
|
4c6aaafe88 | ||
|
|
dc8c099d9e | ||
|
|
259ae674a1 | ||
|
|
731f023c6d | ||
|
|
86b19d4c74 | ||
|
|
17b8c29799 | ||
|
|
29af2849ba | ||
|
|
a7ac5efd70 | ||
|
|
15c7a9dcf8 | ||
|
|
8e55a2a866 | ||
|
|
0f306da63b | ||
|
|
ba9ea5c752 | ||
|
|
53b7d6f89f | ||
|
|
f5fb095df4 | ||
|
|
721919fae9 | ||
|
|
d3e27e87fe | ||
|
|
e1ff92e8c6 | ||
|
|
ac5d744914 | ||
|
|
b94a265fad | ||
|
|
1ba3a92745 | ||
|
|
9814fd705e | ||
|
|
20455f4fc2 | ||
|
|
9f37bf7397 | ||
|
|
892b884745 | ||
|
|
e8dd0a7daf | ||
|
|
26151e39c9 | ||
|
|
453e331014 | ||
|
|
7f72006020 | ||
|
|
3c13df3c2d | ||
|
|
d31af813e2 | ||
|
|
a85dc66a39 | ||
|
|
9492f0ae29 | ||
|
|
51149c75ff | ||
|
|
56bedb821f | ||
|
|
d3bca574aa | ||
|
|
c462bf229f | ||
|
|
8a452c42af | ||
|
|
07f2d74dc3 | ||
|
|
2ce65dc1e0 | ||
|
|
37be06448c | ||
|
|
9c13089a2f | ||
|
|
b642cb2d93 | ||
|
|
9e5d521567 | ||
|
|
6eabc99e01 | ||
|
|
ea917dd811 | ||
|
|
070d8e1731 | ||
|
|
664c60d2bc | ||
|
|
e25814e1ee | ||
|
|
27ea117731 | ||
|
|
7ab156e117 | ||
|
|
f2d415663f | ||
|
|
bdf08a19d1 | ||
|
|
cb90e9f622 | ||
|
|
b05a5e1fb6 | ||
|
|
92a5da1006 | ||
|
|
75a95469b2 | ||
|
|
c0ae287d46 | ||
|
|
a2b92aa3ff | ||
|
|
544a2285d3 | ||
|
|
8c39950ea3 | ||
|
|
6d642fe9b9 | ||
|
|
f175a741bc | ||
|
|
3290376f80 | ||
|
|
2b5c1ba99a | ||
|
|
bcb3f08386 | ||
|
|
b729b9bebd | ||
|
|
26ee91eb48 | ||
|
|
43a17f67a0 | ||
|
|
c71d2db949 | ||
|
|
04f1df8af1 | ||
|
|
1c490aee42 | ||
|
|
c6132df866 | ||
|
|
d8f91cc94c | ||
|
|
568b074809 | ||
|
|
401c16e485 | ||
|
|
17bee6a145 | ||
|
|
8829fba6cf | ||
|
|
e8983abe65 | ||
|
|
01f38c4e33 | ||
|
|
10b99ceb6f | ||
|
|
1140426b73 | ||
|
|
5a82f34801 | ||
|
|
5420d889fe | ||
|
|
d9bb51fdc7 | ||
|
|
9a636a3cfb | ||
|
|
181f82f33e | ||
|
|
6a9cde24b0 | ||
|
|
dc31d9c715 | ||
|
|
45b3f06e1b | ||
|
|
d5f7944ac4 | ||
|
|
3d50caf985 | ||
|
|
4d7ef58e7e | ||
|
|
3e117f4e99 | ||
|
|
888d6f8856 | ||
|
|
9ebf8693d4 | ||
|
|
d8c3127b09 | ||
|
|
b6631f4778 | ||
|
|
2e77bdf11e | ||
|
|
cce75f11ca | ||
|
|
d8b6b39dbb | ||
|
|
fa89057aac | ||
|
|
15db0a8018 | ||
|
|
b7a4d9cea4 | ||
|
|
5b676c36e5 | ||
|
|
32231762ff | ||
|
|
a7096c1599 | ||
|
|
bed428c27e | ||
|
|
873e698352 | ||
|
|
ad13577399 | ||
|
|
31a9c77055 | ||
|
|
bae0c2df5f | ||
|
|
0ed31def68 | ||
|
|
0e7a6ad5ab | ||
|
|
180797540c | ||
|
|
c00babf9b3 | ||
|
|
943681ae3c | ||
|
|
f14ce367d2 | ||
|
|
3eb5766323 | ||
|
|
cd5e8d7b52 | ||
|
|
361d12e97c | ||
|
|
fb4a5a3715 | ||
|
|
9c2585ba86 | ||
|
|
feb6296bb4 | ||
|
|
74eb71c304 | ||
|
|
fa2083f764 | ||
|
|
7111834a99 | ||
|
|
a943c7eddb | ||
|
|
2d089a7bae | ||
|
|
5bba969f0d | ||
|
|
3a43fd34c0 | ||
|
|
d9005b3f53 | ||
|
|
fab9e32175 | ||
|
|
e71c1c2ec4 | ||
|
|
81fb0515fb | ||
|
|
739dfc1434 | ||
|
|
a4e8795666 | ||
|
|
14134d637d | ||
|
|
2b698a9018 | ||
|
|
91684c8a7d | ||
|
|
fbdfe1d9dd | ||
|
|
7221725121 | ||
|
|
640348df3a | ||
|
|
4ed99e017a | ||
|
|
df6b9dd30b | ||
|
|
faf142baff | ||
|
|
f80cb9f553 | ||
|
|
d3eaa1fceb | ||
|
|
df77152851 | ||
|
|
937202b27c | ||
|
|
3581f39c31 | ||
|
|
c1d9c81b68 | ||
|
|
20355a4dd4 | ||
|
|
cf66d7f09b | ||
|
|
30afe81462 | ||
|
|
18ee6e8867 | ||
|
|
9f78a93403 | ||
|
|
bd046e2437 | ||
|
|
e9004a93a4 | ||
|
|
4816a1638a | ||
|
|
22c53392a3 | ||
|
|
bdaa9e831d | ||
|
|
036bcd6b8f | ||
|
|
4d2bc861cf | ||
|
|
98722dc0fd | ||
|
|
629d7c3263 | ||
|
|
5f7af5317a | ||
|
|
8bb1b60964 | ||
|
|
7ef5493414 | ||
|
|
a3ac838221 | ||
|
|
14400d1cb9 | ||
|
|
7d531646fd | ||
|
|
6f6c1435c7 | ||
|
|
332b8b6f34 | ||
|
|
d40a734080 | ||
|
|
94f1dfef52 | ||
|
|
0857dbe465 | ||
|
|
71f19fba58 | ||
|
|
24b18fb0fd | ||
|
|
5731241a5c | ||
|
|
47e70abb4e | ||
|
|
0ede95f375 | ||
|
|
b723efdd3b | ||
|
|
14c513690d | ||
|
|
88f239e784 | ||
|
|
a1f6bf8a67 | ||
|
|
912dcd38df | ||
|
|
da5028cdee | ||
|
|
899faa62f1 | ||
|
|
9df6a644c9 | ||
|
|
1a6d9eaa11 | ||
|
|
7d447af277 | ||
|
|
d8baaab849 | ||
|
|
3e1523f007 | ||
|
|
fa38af025f | ||
|
|
6ca9ff847f | ||
|
|
a8824b2b51 | ||
|
|
6aa3752b16 | ||
|
|
c483a439bf | ||
|
|
74bdf1c681 | ||
|
|
7437d9fe58 | ||
|
|
51f7351962 | ||
|
|
d01fcb921b | ||
|
|
6179c938bf | ||
|
|
dbbcb658a9 | ||
|
|
16f97ad7c3 | ||
|
|
bc7445ed99 | ||
|
|
e4d024cd0d | ||
|
|
1005de8295 | ||
|
|
c79289cedf | ||
|
|
6a745be036 | ||
|
|
cee9cc33ed | ||
|
|
9a5e9313cd | ||
|
|
5401af5812 | ||
|
|
6305a1d1c2 | ||
|
|
95b96e3e9e | ||
|
|
95b3f6d40d | ||
|
|
c258a4bef1 | ||
|
|
647544a0c6 | ||
|
|
7e0a2a879c | ||
|
|
471e1388ae | ||
|
|
1da430b042 | ||
|
|
56ac06c563 | ||
|
|
4dec4bb61c | ||
|
|
99a09c49a3 | ||
|
|
88fd46bfea | ||
|
|
8a6603b3d8 | ||
|
|
f6c9f454a5 | ||
|
|
d8a5426c37 | ||
|
|
c9011dcbfd | ||
|
|
43089fd13c | ||
|
|
bb3bd9c395 | ||
|
|
ba423ab424 | ||
|
|
c23984cac3 | ||
|
|
6685a0fa7e | ||
|
|
ac4750d016 | ||
|
|
951e9fd7f2 | ||
|
|
cbd1554589 | ||
|
|
80c545933f | ||
|
|
594f319fc6 | ||
|
|
102feb9576 | ||
|
|
68274d2862 | ||
|
|
8945b7a4fa | ||
|
|
d5ef93b2ba | ||
|
|
cb0f0dba3a | ||
|
|
7b263be01b | ||
|
|
56df60f520 | ||
|
|
d5cbbc472d | ||
|
|
d987e5628a | ||
|
|
1383191f15 | ||
|
|
27297284cf | ||
|
|
3af3a91c87 | ||
|
|
23c5b71f95 | ||
|
|
2ee6a8ec3a | ||
|
|
10819b8693 | ||
|
|
83c617b452 | ||
|
|
4acb133655 | ||
|
|
6e4135e790 | ||
|
|
f0198b62f3 | ||
|
|
3ff8063ab8 | ||
|
|
8d52f1b279 | ||
|
|
24072d222c | ||
|
|
55c59e71da | ||
|
|
62233788e0 | ||
|
|
b297c5499d | ||
|
|
fb7925f272 | ||
|
|
221e873862 | ||
|
|
e7143e02e2 | ||
|
|
a1d68bd951 | ||
|
|
93ee452a2d | ||
|
|
1abaa5fc17 | ||
|
|
999059bc61 | ||
|
|
39ba39c237 | ||
|
|
009e6c2066 | ||
|
|
8bf03ae706 | ||
|
|
a2fe3f66e3 | ||
|
|
6cd5b253f1 | ||
|
|
abf0461d80 | ||
|
|
abca45e152 | ||
|
|
58ea94f6ac | ||
|
|
49cba92fa1 | ||
|
|
42329fc736 | ||
|
|
68dee49501 | ||
|
|
234837ee1d | ||
|
|
0d3554d70a | ||
|
|
7f6c6c4787 | ||
|
|
b6c975bfdc | ||
|
|
eaf5a86121 | ||
|
|
b9a9dad60a | ||
|
|
a2afc38894 | ||
|
|
b80c92ba93 | ||
|
|
6669a2cedb | ||
|
|
7369da3d8d | ||
|
|
697a0f1ecf | ||
|
|
3db0557b07 | ||
|
|
8178d57ab9 | ||
|
|
f1b2f767bb | ||
|
|
f21b394d21 | ||
|
|
4e4ccca02a | ||
|
|
b6578d6447 | ||
|
|
abeb94a53d | ||
|
|
974a74500b | ||
|
|
61dd17ae5e | ||
|
|
2628249a51 | ||
|
|
5f57782199 | ||
|
|
bceb49ee6c | ||
|
|
beeb59f263 | ||
|
|
4150c87be0 | ||
|
|
a394d8211e | ||
|
|
6a162776f2 | ||
|
|
d41bd7b133 | ||
|
|
f3409fab29 | ||
|
|
dd75fbfee2 | ||
|
|
ae2c85f947 | ||
|
|
c0b454a5de | ||
|
|
27754dd0d7 | ||
|
|
18ec830882 | ||
|
|
1ffc0f552e | ||
|
|
07b676ac81 | ||
|
|
da79f09544 | ||
|
|
993b035285 | ||
|
|
3f2df643e7 | ||
|
|
42c7649176 | ||
|
|
2722d2f5ce | ||
|
|
f71e61d7d9 | ||
|
|
73c76cab77 | ||
|
|
43e8a533b7 | ||
|
|
ea4203bb32 | ||
|
|
568b5073c8 | ||
|
|
471e1f4827 | ||
|
|
b9185a6fcd | ||
|
|
80496aa94c | ||
|
|
5fd6e3c1a8 | ||
|
|
54590c1700 | ||
|
|
b1259be8f2 | ||
|
|
cd161e4b16 | ||
|
|
cb4214fe6e | ||
|
|
9d42751a42 | ||
|
|
c2c637b359 | ||
|
|
2f446e11d6 | ||
|
|
4f566b088c | ||
|
|
0d40d87b31 | ||
|
|
70fcd6bf40 | ||
|
|
94c0095b3b | ||
|
|
4328060637 | ||
|
|
d98d0fd5bd | ||
|
|
5db2863d08 | ||
|
|
ff5e438d6d | ||
|
|
bfd5f13ee9 | ||
|
|
8043188f36 | ||
|
|
e3e0998772 | ||
|
|
86adc6f282 | ||
|
|
b51b519d30 | ||
|
|
c70dcb6a59 | ||
|
|
2486c7dba0 | ||
|
|
1456fcdcad | ||
|
|
a216800c72 | ||
|
|
c3d8597c13 | ||
|
|
844663ce1a | ||
|
|
055e6af7b7 | ||
|
|
479e6ecddc | ||
|
|
b9456e8244 | ||
|
|
432dfef435 | ||
|
|
429c6f7a48 | ||
|
|
6d41f6c56d | ||
|
|
20ac2b86cf | ||
|
|
b88455166a | ||
|
|
9b86de1f9d | ||
|
|
1393c72281 | ||
|
|
bcb538aee2 | ||
|
|
01e8f8c649 | ||
|
|
1119cf3af9 | ||
|
|
216934145c | ||
|
|
40f952cac3 | ||
|
|
330e4a7724 | ||
|
|
e676503e02 | ||
|
|
06233fbb2f | ||
|
|
17298695b1 | ||
|
|
c1081ccfe2 | ||
|
|
30da5a8643 | ||
|
|
55bf5436e4 | ||
|
|
a4956dc649 | ||
|
|
512b7bd429 | ||
|
|
5119c51439 | ||
|
|
f3e25f3277 | ||
|
|
1275c70187 | ||
|
|
be69fc448d | ||
|
|
bcccefe98e | ||
|
|
2061f38d9e | ||
|
|
d0869d9087 | ||
|
|
1eabf316d6 | ||
|
|
a0dd750a52 | ||
|
|
2fc9885abc | ||
|
|
14d683fb9a | ||
|
|
e286519cb1 | ||
|
|
b1e78a3562 | ||
|
|
0bc103658a | ||
|
|
9037b9b4fa | ||
|
|
d194493e9a | ||
|
|
aa22344cdb | ||
|
|
736e7b822e | ||
|
|
2ebda95036 | ||
|
|
d8783eaad4 | ||
|
|
cddb08de1a | ||
|
|
d4e5d3df54 | ||
|
|
414b03ce74 | ||
|
|
96dbab8834 | ||
|
|
03a110a750 | ||
|
|
6accc705be | ||
|
|
312dca003b | ||
|
|
4f9fdb6c14 | ||
|
|
94af06466b | ||
|
|
7cf2686097 | ||
|
|
f14883aa11 | ||
|
|
9df8de2386 | ||
|
|
8b2cf4705e | ||
|
|
364e9832ac | ||
|
|
2deeb61f17 | ||
|
|
14498e8a9c | ||
|
|
eb78022387 | ||
|
|
3677a59a78 | ||
|
|
7c1c840a59 | ||
|
|
a73eaf5d37 | ||
|
|
68989a58a8 | ||
|
|
9841731ae7 | ||
|
|
ba7ac5d439 | ||
|
|
7c60772b26 | ||
|
|
1141a5d3af | ||
|
|
6f74fd1f98 | ||
|
|
75873bfcfa | ||
|
|
1faf621f17 | ||
|
|
1d1c73dfcc | ||
|
|
d057ce0a85 | ||
|
|
0ce26d2c08 | ||
|
|
abf285d713 | ||
|
|
c2ee8e3999 | ||
|
|
167ba0c68f | ||
|
|
9ad1cbe920 | ||
|
|
313ea52e3d | ||
|
|
3acfb7a83f | ||
|
|
783dae2bbb | ||
|
|
59681b211b | ||
|
|
98438175cf | ||
|
|
af40302e5f | ||
|
|
ec0e0ae449 | ||
|
|
607ff17033 | ||
|
|
e73e610669 | ||
|
|
30fddde066 | ||
|
|
a56d2842fb | ||
|
|
35f59a47cc | ||
|
|
817d57bd12 | ||
|
|
5826048e7b | ||
|
|
1a975b31cf | ||
|
|
73298a80f0 | ||
|
|
a5d14ef4c1 | ||
|
|
d0c79b65f8 | ||
|
|
2fc50b1a1f | ||
|
|
0ddeedb0b3 | ||
|
|
09c2fb10f3 | ||
|
|
5bfff5b7ba | ||
|
|
702088375c | ||
|
|
ea507fbcc4 | ||
|
|
0ff1e6632b | ||
|
|
996ee47f96 | ||
|
|
3e9bd5bb62 | ||
|
|
ee7221c986 | ||
|
|
318c126ae3 | ||
|
|
2154aea89f | ||
|
|
4d3ad1af35 | ||
|
|
75cab7688f | ||
|
|
5084d6dd97 | ||
|
|
518f80cbb6 | ||
|
|
c9399efa65 | ||
|
|
dd9133659c | ||
|
|
d3016b7eb5 | ||
|
|
69e884f5b7 | ||
|
|
6d122905f4 | ||
|
|
e6e016ac2d | ||
|
|
3e7925e33f | ||
|
|
7a2ccba63c | ||
|
|
be2134eb69 | ||
|
|
95e422b0e1 | ||
|
|
53d9c4ca95 | ||
|
|
30948ab545 | ||
|
|
906df6b401 | ||
|
|
b9c585bab5 | ||
|
|
12203140ad | ||
|
|
0704152e38 | ||
|
|
f582efe98d | ||
|
|
540579f520 | ||
|
|
24c348dc49 | ||
|
|
4b4c245507 | ||
|
|
400f68d1aa | ||
|
|
5bb27ed9cd | ||
|
|
833498c269 | ||
|
|
80507d487b | ||
|
|
08f4ebaaf8 | ||
|
|
4c418525eb | ||
|
|
4962f6c926 | ||
|
|
50f0e9298c | ||
|
|
89efcc5db1 | ||
|
|
c3119a5632 | ||
|
|
069bbd92b0 | ||
|
|
c4422a2593 | ||
|
|
3aab9d368e | ||
|
|
b6afab63b2 | ||
|
|
b93f5e9c44 | ||
|
|
630082035f | ||
|
|
c74e41fc76 | ||
|
|
08ce7c58b5 | ||
|
|
1853fde379 | ||
|
|
f29d22ca95 | ||
|
|
5ea5f928ab | ||
|
|
efd6d35eb3 | ||
|
|
2b2538f13a | ||
|
|
9375dae179 | ||
|
|
674bb3758d | ||
|
|
cedf9a2eb8 | ||
|
|
7d2dc5b6c6 | ||
|
|
9d2aad7bf9 | ||
|
|
f085d7609b | ||
|
|
a49243a42a | ||
|
|
e79f431f14 | ||
|
|
38e5b6e8e3 | ||
|
|
35bdb785c4 | ||
|
|
25cb146fde | ||
|
|
c10f0f4a9e | ||
|
|
3a3a7f6e16 | ||
|
|
1d3b500962 | ||
|
|
f39f95af6d | ||
|
|
6fec2bbe1c | ||
|
|
2412134073 | ||
|
|
136545d1fd | ||
|
|
684c4d2113 | ||
|
|
6624fd0401 | ||
|
|
31502d2da3 | ||
|
|
3ee39ecca3 | ||
|
|
89e7c305e7 | ||
|
|
60dd71c59e | ||
|
|
0936f77930 | ||
|
|
3c09b95a8c | ||
|
|
780f26f135 | ||
|
|
77618674a0 | ||
|
|
c9c89a6005 | ||
|
|
d1276c4299 | ||
|
|
69730b6c95 | ||
|
|
9147d30152 | ||
|
|
6217c70fb5 | ||
|
|
17352c9a56 | ||
|
|
1b6026304f | ||
|
|
91f9973c6c | ||
|
|
ca2acee38a | ||
|
|
3bd455ced2 | ||
|
|
2c25abd143 | ||
|
|
08a9fb8cd7 | ||
|
|
d8a38b4e35 | ||
|
|
e64660f2d8 | ||
|
|
1a11466e69 | ||
|
|
78ab2fbe09 | ||
|
|
0c45d5773a | ||
|
|
f48335444b | ||
|
|
81b33cee5c | ||
|
|
020dcaad75 | ||
|
|
9bc56bcfc7 | ||
|
|
8325fadeb3 | ||
|
|
d54275b3bd | ||
|
|
29d20423a3 | ||
|
|
e539816253 | ||
|
|
922ce9ef5f | ||
|
|
b73ec6ae94 | ||
|
|
4a11bf956d | ||
|
|
3b3bb6c80a | ||
|
|
0f323ff2e3 | ||
|
|
3305c65ae6 | ||
|
|
5c5acdcb03 | ||
|
|
0e6991f486 | ||
|
|
014786cc5f | ||
|
|
223c6b50fc | ||
|
|
b18946352e | ||
|
|
96012b26b7 | ||
|
|
31cd663ad5 | ||
|
|
0e9c9d7ccf | ||
|
|
2a6eb6ec86 | ||
|
|
0a74423c07 | ||
|
|
6f1302ae67 | ||
|
|
f275570f12 | ||
|
|
90b47f6c44 | ||
|
|
e73d008695 | ||
|
|
3c5d1b402c | ||
|
|
3e22bccce4 | ||
|
|
354e140305 | ||
|
|
54859f3582 | ||
|
|
da12efd675 | ||
|
|
32f848e90d | ||
|
|
32440d23f7 | ||
|
|
62b7acc93a | ||
|
|
7b8e2c75c2 | ||
|
|
03abc641c5 | ||
|
|
fa5b98c9b5 | ||
|
|
c681be7ba8 | ||
|
|
3d3305a312 | ||
|
|
bb305af7b4 | ||
|
|
fd284973b6 | ||
|
|
5d57572694 | ||
|
|
36a22f2b3c | ||
|
|
dea9b590d1 | ||
|
|
bf843fe598 | ||
|
|
a23bc6caa8 | ||
|
|
1904fd5b02 | ||
|
|
03c9a883e1 | ||
|
|
c06df267a3 | ||
|
|
0bccdfeda7 | ||
|
|
07d118ae7d | ||
|
|
e912dde08d | ||
|
|
3544375fdd | ||
|
|
ab6ca7910e | ||
|
|
6a329f7a8e | ||
|
|
5d4bb10106 | ||
|
|
cbc079bfff | ||
|
|
09358d5853 | ||
|
|
81c345f33e | ||
|
|
3aa200eacc | ||
|
|
6ce0b60cf2 | ||
|
|
faef0784ee | ||
|
|
fb70fe5760 | ||
|
|
5b75b8a89e | ||
|
|
fa0296b796 | ||
|
|
4e2d1f568f | ||
|
|
b8d1aec1e5 | ||
|
|
38cfd6985e | ||
|
|
d7c20c6941 | ||
|
|
7894a54a0e | ||
|
|
a46e64eec3 | ||
|
|
cae0399584 | ||
|
|
bfbf4ef0b5 | ||
|
|
ca4004605e | ||
|
|
ec565a1bd3 | ||
|
|
94c4b180c1 | ||
|
|
66de0b9019 | ||
|
|
f752b38228 | ||
|
|
d79748a967 | ||
|
|
c1b6c2c5a5 | ||
|
|
806b04e0ca | ||
|
|
736b562f3a | ||
|
|
db440236fc | ||
|
|
00ea8b900a | ||
|
|
e092e9ba67 | ||
|
|
8313cf34a6 | ||
|
|
8f4b8f5826 | ||
|
|
c607b01f33 | ||
|
|
cc5d01d0e2 | ||
|
|
a4cc41b679 | ||
|
|
67361e9ed5 | ||
|
|
8662572690 | ||
|
|
99ea1788e7 | ||
|
|
7bec3c90cd | ||
|
|
ca4e6c46bc | ||
|
|
678da159a9 | ||
|
|
cc3b51fb3b | ||
|
|
060344bb5a | ||
|
|
b42c67040d | ||
|
|
f3b18fcf0e | ||
|
|
a86c69edc9 | ||
|
|
55c60a05dc | ||
|
|
ecf40cc747 | ||
|
|
197458e60b | ||
|
|
0c3ffb0743 | ||
|
|
56dffd3c58 | ||
|
|
57a3a37fdd | ||
|
|
a8a273f0d8 | ||
|
|
9f4ab26696 | ||
|
|
4ddef9d648 | ||
|
|
7cccca8194 | ||
|
|
2a8b678a4b | ||
|
|
b9767b865a | ||
|
|
f6bc3eb014 | ||
|
|
007917df19 | ||
|
|
22a2e850bf | ||
|
|
1cfdf3613c | ||
|
|
fe280e6bb1 | ||
|
|
a330fe6017 | ||
|
|
4ee4ad25b0 | ||
|
|
777a661389 | ||
|
|
8174230afe | ||
|
|
e1777dc533 | ||
|
|
390731c07b | ||
|
|
25d475e165 | ||
|
|
1e60250670 | ||
|
|
f6d2dd520c | ||
|
|
4600588e72 | ||
|
|
825ca94080 | ||
|
|
7f674f9861 | ||
|
|
27dba7e4e1 | ||
|
|
44295ff248 | ||
|
|
dc33d96a54 | ||
|
|
4ff7619356 | ||
|
|
cc5c2bd7cd | ||
|
|
2884712685 | ||
|
|
027264588b | ||
|
|
ddd75ce730 | ||
|
|
4bc13c28dd | ||
|
|
7a1db89a6e | ||
|
|
c08489509a | ||
|
|
7054ae8a88 | ||
|
|
d7e913be95 | ||
|
|
f283a2ced5 | ||
|
|
c7274ba16f | ||
|
|
6f323e379c | ||
|
|
42212b409a | ||
|
|
e8506cc5f1 | ||
|
|
d387f9f1fa | ||
|
|
73a555788d | ||
|
|
be58f67115 | ||
|
|
b26117a65d | ||
|
|
34fe6182c8 | ||
|
|
ee3ae6025f | ||
|
|
df9812b2a3 | ||
|
|
113eea04cc | ||
|
|
57f9ebdb68 | ||
|
|
94d0e28ad7 | ||
|
|
cd553d45cc | ||
|
|
d993f9ac64 | ||
|
|
833bdc13bd | ||
|
|
33657b4b49 | ||
|
|
ec6bc8e36b | ||
|
|
799370f753 | ||
|
|
abd404c57c | ||
|
|
037ed3cd54 | ||
|
|
c461a7fa15 | ||
|
|
8fc8aaa6dd | ||
|
|
2bc45e2b2e | ||
|
|
cdfc58d115 | ||
|
|
bb8a57d2e9 | ||
|
|
5e52339135 | ||
|
|
df75914e30 | ||
|
|
572e6ccb37 | ||
|
|
8e1ebe28c0 | ||
|
|
adec044e02 | ||
|
|
b9868cc709 | ||
|
|
fce8b125f8 | ||
|
|
4befd2e4ff | ||
|
|
38cdc1b7ba | ||
|
|
a0f6018469 | ||
|
|
f230d55031 | ||
|
|
2f6a15a9ae | ||
|
|
04d751208f | ||
|
|
7cfc40f328 | ||
|
|
3c54d32b6d | ||
|
|
ece7d92e57 | ||
|
|
8e736b28af | ||
|
|
92ec0a5b1d | ||
|
|
398834f690 | ||
|
|
28e6dd8759 | ||
|
|
dedc937915 | ||
|
|
732f4241fe | ||
|
|
873585e1ae | ||
|
|
71a5a02e8c | ||
|
|
51fbd02b40 | ||
|
|
763eda5038 | ||
|
|
6cdb76503b | ||
|
|
aa8edd7a47 | ||
|
|
535aa56627 | ||
|
|
db0fb30f7b | ||
|
|
7619fb4753 | ||
|
|
0aeba954d4 | ||
|
|
2bc1468fa2 | ||
|
|
4b29b6efc5 | ||
|
|
26b1003cfd | ||
|
|
b696dce6e4 | ||
|
|
403a86feca | ||
|
|
56d6a9767e | ||
|
|
d2cc229622 | ||
|
|
e6b166da7d | ||
|
|
77f401d977 | ||
|
|
7d7b232fdb | ||
|
|
959f1e33cd | ||
|
|
7f5ab96f81 | ||
|
|
443089a66f | ||
|
|
f5d9b47177 | ||
|
|
a0cddbe9b3 | ||
|
|
5f7fcfd3df | ||
|
|
a39080340a | ||
|
|
a3d6879c55 | ||
|
|
b09be86a3c | ||
|
|
02ef033d23 | ||
|
|
f10861e1de | ||
|
|
ecf53d9961 | ||
|
|
5339c09b72 | ||
|
|
b6ad218126 | ||
|
|
b7b74a429e | ||
|
|
52acd3123f | ||
|
|
c9c3a689d8 | ||
|
|
da4a2a2494 | ||
|
|
35a1fb26f9 | ||
|
|
cb3723242c | ||
|
|
6a0c6284d0 | ||
|
|
114ade7456 | ||
|
|
a01e0e37f4 | ||
|
|
18884025de | ||
|
|
cfdc941207 | ||
|
|
5eaf00ba0e | ||
|
|
8948555ac1 | ||
|
|
e28418d6d6 | ||
|
|
fe83c53206 | ||
|
|
942aa08285 | ||
|
|
93dd6b5a98 | ||
|
|
08dd9ca91c | ||
|
|
77efdc3ccf | ||
|
|
ef1bcd5afa | ||
|
|
8636685252 | ||
|
|
5873dfb731 | ||
|
|
934abec88c | ||
|
|
c1d654c4ce | ||
|
|
d64b12b14c | ||
|
|
3f4ab5f95e | ||
|
|
ee1e94be96 | ||
|
|
1e9999a8d3 | ||
|
|
460ca99fe1 | ||
|
|
7fdf9b7012 | ||
|
|
c16b869fea | ||
|
|
8deb19e3ac | ||
|
|
e6d4445a8a | ||
|
|
0f0da809da | ||
|
|
db8e805a96 | ||
|
|
a882cc7e8e | ||
|
|
acede26aa6 | ||
|
|
9330919be8 | ||
|
|
91b4e91e9c | ||
|
|
2fb265ae2d | ||
|
|
3b5e7f1dc4 | ||
|
|
08ff286f9a | ||
|
|
bc9fe2f4f9 | ||
|
|
e99b168bd6 | ||
|
|
a7afb1f680 | ||
|
|
6f3934f2e5 | ||
|
|
79da297add | ||
|
|
6664535ab9 | ||
|
|
80d290e178 | ||
|
|
d144af6d8e | ||
|
|
aba7c13a1d | ||
|
|
f59d3f36d1 | ||
|
|
3f0d0ecd5f | ||
|
|
0c51502cc5 | ||
|
|
e829650cd9 | ||
|
|
a8082c551b | ||
|
|
ff55cfa001 | ||
|
|
623a3d3b7b | ||
|
|
fb32e2a561 | ||
|
|
8aa8a380e1 | ||
|
|
f35b8b05e8 | ||
|
|
05bb73bb7c | ||
|
|
18299dc65e | ||
|
|
818ab2c10f | ||
|
|
df0bf28d57 | ||
|
|
ff65f10c2f | ||
|
|
5cf49aa166 | ||
|
|
0651daa1d4 | ||
|
|
921c53f75c | ||
|
|
dd37519185 | ||
|
|
a1e8c4eb2b | ||
|
|
1f8c191cb3 | ||
|
|
f4acc74eee | ||
|
|
3d1378ab77 | ||
|
|
58e4174edb | ||
|
|
20b4585666 | ||
|
|
9c7e7ed8d4 | ||
|
|
436c4f2736 | ||
|
|
0ce752af79 | ||
|
|
92ff896bdb | ||
|
|
77a3cbaba5 | ||
|
|
56f9c88251 | ||
|
|
8a5a08cbe1 | ||
|
|
5241c38ba0 | ||
|
|
072a903351 | ||
|
|
328bd453bb | ||
|
|
690a3cfa68 | ||
|
|
1c1847f63c | ||
|
|
c3d9d8ee2f | ||
|
|
65932b65d2 | ||
|
|
682e961416 | ||
|
|
9fcccc8197 | ||
|
|
72f3ced219 | ||
|
|
74de066529 | ||
|
|
3d1589404c | ||
|
|
30d9d46dd8 | ||
|
|
740373897a | ||
|
|
f7ca01bafd | ||
|
|
7654ff686a | ||
|
|
5266612bb3 | ||
|
|
a9b46a4d63 | ||
|
|
76e9bd8ad6 | ||
|
|
317a443644 | ||
|
|
43f91ca42c | ||
|
|
8d78d07415 | ||
|
|
99a00a1ae2 | ||
|
|
2cd8d891a1 | ||
|
|
7fc33af1e5 | ||
|
|
67c57a1137 | ||
|
|
9f8ac06659 | ||
|
|
aea28b28d0 | ||
|
|
ee4cd61696 | ||
|
|
e9f15c377f | ||
|
|
d5935ea81b | ||
|
|
934ad96a98 | ||
|
|
2c68f8fba1 | ||
|
|
c90de87f37 | ||
|
|
ab84566d86 | ||
|
|
4c109a467f | ||
|
|
bc4f6aaf9c | ||
|
|
cf8ac7e8b3 | ||
|
|
3a9b230aef | ||
|
|
016b644d86 | ||
|
|
7082b47856 | ||
|
|
57ec382102 | ||
|
|
9748ed2259 | ||
|
|
6ec5981f1d | ||
|
|
e20ea342c2 | ||
|
|
2ff3603245 | ||
|
|
da6e8f14d6 | ||
|
|
2dd04739b5 | ||
|
|
8e758ea979 | ||
|
|
a81f7e2a24 | ||
|
|
c98ec3658c | ||
|
|
249463f7df | ||
|
|
700e77ad43 | ||
|
|
1a272879f1 | ||
|
|
aa6cb4f25b | ||
|
|
59eec36746 | ||
|
|
45baff403a | ||
|
|
5de1883390 | ||
|
|
35b0d213a6 | ||
|
|
774a4b7533 | ||
|
|
11cbb774bc | ||
|
|
0f7d0a03d9 | ||
|
|
cb568a1af4 | ||
|
|
f4da03d840 | ||
|
|
e5cc8123b9 | ||
|
|
cc13e1210d | ||
|
|
1e838f2e55 | ||
|
|
154d4170cc | ||
|
|
64d6163f13 | ||
|
|
85ffc5d8bf | ||
|
|
38f36d465c | ||
|
|
d956055795 | ||
|
|
c1e1cd0596 | ||
|
|
a3df2ca0ef | ||
|
|
6b3325d0ba | ||
|
|
9e4dd44a2e | ||
|
|
e880588aac | ||
|
|
c2af3df331 | ||
|
|
46be6e37dc | ||
|
|
5165077bc9 | ||
|
|
5ae537f23c | ||
|
|
5f572dbd04 | ||
|
|
d511e80b01 | ||
|
|
27dfa41b67 | ||
|
|
f55c28352e | ||
|
|
a7b884d170 | ||
|
|
fd4f996c30 | ||
|
|
c897037b7a | ||
|
|
11fe64eee3 | ||
|
|
6cbc0f0304 | ||
|
|
b3d28bac6a | ||
|
|
96833bdf89 | ||
|
|
6cf5730bcb | ||
|
|
e5403f8dfd | ||
|
|
8278992feb | ||
|
|
9f690c1f5d | ||
|
|
b946f7e697 | ||
|
|
c9dea854f6 | ||
|
|
e72dfe5af2 | ||
|
|
d5912a53f4 | ||
|
|
cb5d005e68 | ||
|
|
0dd0f39250 | ||
|
|
9c7e250109 | ||
|
|
ca103b6af3 | ||
|
|
2f75ee9472 | ||
|
|
7eab38afa7 | ||
|
|
68d0a442e4 | ||
|
|
ee2b6d3b85 | ||
|
|
e73220e069 | ||
|
|
d2a1404f04 | ||
|
|
c8a7eb4988 | ||
|
|
7ec37e058e | ||
|
|
64f2d2a502 | ||
|
|
6afb4ccf26 | ||
|
|
a4676d1fea | ||
|
|
97173de555 | ||
|
|
9e6d01b2a1 | ||
|
|
d3a5437079 | ||
|
|
b22a03a317 | ||
|
|
06cd13aef2 | ||
|
|
25a3feb2ca | ||
|
|
c8c3332366 | ||
|
|
006b315120 | ||
|
|
f74d6efcae | ||
|
|
b2d802aa85 | ||
|
|
964a51e21d | ||
|
|
4a43db06dd | ||
|
|
3ce7fe638f | ||
|
|
c2a4d44bf4 | ||
|
|
867817f568 | ||
|
|
46a56a236f | ||
|
|
6357009055 | ||
|
|
42f7091038 | ||
|
|
a3c63fcdf0 | ||
|
|
6b358c626f | ||
|
|
3bbfa822d7 | ||
|
|
a13fc138f2 | ||
|
|
721a082758 | ||
|
|
07288de5a1 | ||
|
|
ac0bb78412 | ||
|
|
c24464179b | ||
|
|
d473600a15 | ||
|
|
accd9eaa27 | ||
|
|
cb180cbbf8 | ||
|
|
a3dbe482e2 | ||
|
|
959302a868 | ||
|
|
95be2b55f7 | ||
|
|
3bce86a1e8 | ||
|
|
dd10931316 | ||
|
|
f5b8f5a6f8 | ||
|
|
65fddc5d28 | ||
|
|
d3ac843249 | ||
|
|
1b5f4f5c3c | ||
|
|
1af558af44 | ||
|
|
b3b36f3340 | ||
|
|
4624659af6 | ||
|
|
ab649af8be | ||
|
|
c5491e6f27 | ||
|
|
b47b5ddb05 | ||
|
|
095799a816 | ||
|
|
1104b6daa4 | ||
|
|
4ecd811302 | ||
|
|
b112ccd6d8 | ||
|
|
bee32f9898 | ||
|
|
69fce590e3 | ||
|
|
c51ed43a10 | ||
|
|
fd51511380 | ||
|
|
8a054d8cc9 | ||
|
|
91731896c4 | ||
|
|
e897d04218 | ||
|
|
69e4de6ba9 | ||
|
|
6b176066ec | ||
|
|
4c372962fc | ||
|
|
001f386244 | ||
|
|
5eb73e0c05 | ||
|
|
3347f92414 | ||
|
|
72c6200f17 | ||
|
|
ed01ee1e2d | ||
|
|
b259bc60a2 | ||
|
|
772d5e10b8 | ||
|
|
7e96560fbb | ||
|
|
6ae5e11c6f | ||
|
|
9877fe2eed | ||
|
|
fe086e90a1 | ||
|
|
c9958e1634 | ||
|
|
67f7c002c9 | ||
|
|
bf7c38d8e8 | ||
|
|
f361d153d1 | ||
|
|
0e571c3e35 | ||
|
|
7857c80c79 | ||
|
|
99adfd2bba | ||
|
|
9a493491f1 | ||
|
|
1ac76d7758 | ||
|
|
c5ecf48d94 | ||
|
|
1e10f021b5 | ||
|
|
7d0bd49ae3 | ||
|
|
d4e7cabee5 | ||
|
|
92471b0beb | ||
|
|
ea713758a1 | ||
|
|
9182d8d594 | ||
|
|
7df3434c6a | ||
|
|
5e9014b2c3 | ||
|
|
4d95c824f3 | ||
|
|
28d7d2544e | ||
|
|
decc56e54d | ||
|
|
976d86ae1a | ||
|
|
4e650e17aa | ||
|
|
d08d04debd | ||
|
|
602108b150 | ||
|
|
a9b1a2e7b7 | ||
|
|
99f31bbc23 | ||
|
|
6c2faf68c4 | ||
|
|
ee8c29c5ef | ||
|
|
26df916421 | ||
|
|
0a8f400a59 | ||
|
|
cc1cbd1ed7 | ||
|
|
034e85aa87 | ||
|
|
12e54e189a | ||
|
|
5eaea1c7f1 | ||
|
|
10786c6ca8 | ||
|
|
55d9377403 | ||
|
|
70f29785ca | ||
|
|
e197c5120d | ||
|
|
2cf72aea81 | ||
|
|
30111bb125 | ||
|
|
7d38f6b074 | ||
|
|
7e625b8e9e | ||
|
|
152eea3cb8 | ||
|
|
ee72b1be5d | ||
|
|
605d96b71b | ||
|
|
8e1c7d955f | ||
|
|
8046b5675f | ||
|
|
0ac8a39c5e | ||
|
|
81522b33e6 | ||
|
|
4df49689a9 | ||
|
|
0f7106bf4a | ||
|
|
900c5b7661 | ||
|
|
5cac4c953d | ||
|
|
65f2cb9a22 | ||
|
|
7ddb68b70d | ||
|
|
14eb66c87d | ||
|
|
ef141d499b | ||
|
|
1ab27e8fe3 | ||
|
|
145a3b7ee4 | ||
|
|
a042327741 | ||
|
|
4eba651c3d | ||
|
|
ba3b2ea66f | ||
|
|
c48719dfdb | ||
|
|
1680f0ef52 | ||
|
|
ae6c4b2ddf | ||
|
|
8e9192181d | ||
|
|
a2f2a59c21 | ||
|
|
e739c26f2e | ||
|
|
b215eae914 | ||
|
|
1123e4e751 | ||
|
|
203bc26c0e | ||
|
|
fb4651bdad | ||
|
|
09f2926bbb | ||
|
|
eef06425a3 | ||
|
|
b329e3c43c | ||
|
|
04a3223ff5 | ||
|
|
9226be058c | ||
|
|
2dc425b083 | ||
|
|
c5f915651c | ||
|
|
e2d7fec793 | ||
|
|
d3b4f46b25 | ||
|
|
6311156169 | ||
|
|
695a814eb3 | ||
|
|
5ef2e35685 | ||
|
|
8818ed9d7b | ||
|
|
d785af1826 | ||
|
|
398811a14e | ||
|
|
c5f9533d2b | ||
|
|
aaf17aa2b2 | ||
|
|
3e11379e6c | ||
|
|
f78d0b7c7a | ||
|
|
978e19c817 | ||
|
|
1550e32282 | ||
|
|
7fb2dc6500 | ||
|
|
92654af609 | ||
|
|
c10787dbb3 | ||
|
|
4fecb7fad9 | ||
|
|
01a121868b | ||
|
|
a023009dee | ||
|
|
e301393f33 | ||
|
|
39600fb0f5 | ||
|
|
663cde7676 | ||
|
|
dac771c096 | ||
|
|
b8b1d572b4 | ||
|
|
6789e61488 | ||
|
|
051fdfb081 | ||
|
|
1f07a827ec | ||
|
|
81618d2efc | ||
|
|
6f44a88ffd | ||
|
|
4300c3d550 | ||
|
|
5fbf7b3d24 | ||
|
|
eb5899c94b | ||
|
|
5e68fa1255 | ||
|
|
f1c322fe69 | ||
|
|
580520f100 | ||
|
|
40343df255 | ||
|
|
57f8b427db | ||
|
|
f85e96acac | ||
|
|
bff83f1785 | ||
|
|
ca27748799 | ||
|
|
2dc98f682f | ||
|
|
d4f3309ffd | ||
|
|
821777bd64 | ||
|
|
84c2fa9491 | ||
|
|
d193c677c7 | ||
|
|
cbfc7c8b43 | ||
|
|
6a43065316 | ||
|
|
9dd390f7a7 | ||
|
|
6c631cb11e | ||
|
|
817b790757 | ||
|
|
98aa8cc22a | ||
|
|
e9e228abaf | ||
|
|
909bb6f6cf | ||
|
|
e8b47eef2f | ||
|
|
415ba26efe | ||
|
|
777e2744c4 | ||
|
|
53a09f4989 | ||
|
|
e3e0f056a9 | ||
|
|
b6ce1fbd51 | ||
|
|
7267cfdbfc | ||
|
|
fa259aa194 | ||
|
|
da1d2873d5 | ||
|
|
be88d278c6 | ||
|
|
81cb8c83bf | ||
|
|
eee44a9919 | ||
|
|
4f730410bc | ||
|
|
171144be80 | ||
|
|
5c2bcba000 | ||
|
|
5b5c6e975d | ||
|
|
45110f60c3 | ||
|
|
26c434c4ee | ||
|
|
2e872d4818 | ||
|
|
30a1219f9d | ||
|
|
cf1632f80b | ||
|
|
885b003730 | ||
|
|
a9a61b2617 | ||
|
|
b968d8594c | ||
|
|
d7ebb871bb | ||
|
|
6f67b2381a | ||
|
|
2237d7e860 | ||
|
|
6ea456d6da | ||
|
|
f0a2edf7cf | ||
|
|
881fcd4e9b | ||
|
|
8954af5c53 | ||
|
|
e3c6d5859b | ||
|
|
16441b5b6a | ||
|
|
195b1ccfcc | ||
|
|
b3f5670cc0 | ||
|
|
e43c80b4f5 | ||
|
|
931e2f6134 | ||
|
|
e091a37241 | ||
|
|
5f093846a7 | ||
|
|
dcbae0618c | ||
|
|
4d70d6319b | ||
|
|
09484667f0 | ||
|
|
04fcf57d0a | ||
|
|
8436dd5851 | ||
|
|
bbae8cccfb | ||
|
|
044fa2d10f | ||
|
|
2dd50cccd3 | ||
|
|
c05ffb0c6b | ||
|
|
935044d2da | ||
|
|
6ec6505a5d | ||
|
|
96e0f55c61 | ||
|
|
b765f06dfd | ||
|
|
8da6318cc6 | ||
|
|
0fcdec604c | ||
|
|
3edda36a91 | ||
|
|
97d65bfca0 | ||
|
|
66771c6f62 | ||
|
|
e6b23aee18 | ||
|
|
5e9ee50f99 | ||
|
|
93584bc766 | ||
|
|
a89180ea06 | ||
|
|
4983da7efa | ||
|
|
8fd6bd4c71 | ||
|
|
c7ea62a394 | ||
|
|
fc8e2d3e05 | ||
|
|
6cf3c91293 | ||
|
|
e122278ec4 | ||
|
|
7c9b5cba1c | ||
|
|
a86c1b7cd3 | ||
|
|
dd6d08d61d | ||
|
|
0fc120d7d5 | ||
|
|
6e03558dcb | ||
|
|
b327dd31b7 | ||
|
|
da1326a336 | ||
|
|
d22cb1dfa7 | ||
|
|
5556915564 | ||
|
|
4c6fc53ba5 | ||
|
|
626b6500de | ||
|
|
dbbbb6b921 | ||
|
|
d9e3d4dbae | ||
|
|
92648de3b4 | ||
|
|
4f9e5b9336 | ||
|
|
d55d0ad621 | ||
|
|
4edbe2aace | ||
|
|
ba2702cfca | ||
|
|
eba1f6327d | ||
|
|
1ba0b4037c | ||
|
|
49daa75bc4 | ||
|
|
cd21138b3d | ||
|
|
fea1eb1149 | ||
|
|
9a58f6c454 | ||
|
|
66cefe6bb5 | ||
|
|
23510acf40 | ||
|
|
faa49f36e7 | ||
|
|
a5fb8b20a1 | ||
|
|
e14b303609 | ||
|
|
2ec3df6680 | ||
|
|
1f4b6001ef | ||
|
|
6e7c9cc6a3 | ||
|
|
2db385c6a5 | ||
|
|
bd27f48eae | ||
|
|
98a33250f6 | ||
|
|
8f9729a928 | ||
|
|
1a8564bc35 | ||
|
|
76c9632417 | ||
|
|
2370361b43 | ||
|
|
cb63095d3f | ||
|
|
601f2fb450 | ||
|
|
e746f17167 | ||
|
|
5f76097562 | ||
|
|
03756c4210 | ||
|
|
5e1e158414 | ||
|
|
76d2525fd2 | ||
|
|
ec8c7e5c2c | ||
|
|
0a4cbe1a08 | ||
|
|
c228421a38 | ||
|
|
a742f82370 | ||
|
|
213678ca3e | ||
|
|
e1b7ad6a71 | ||
|
|
8b9985a92c | ||
|
|
f276826b09 | ||
|
|
8c1df551ef | ||
|
|
b62cb157e1 | ||
|
|
045c74ce67 | ||
|
|
911e902da4 | ||
|
|
4e0d90d720 | ||
|
|
7b62705cc0 | ||
|
|
bdf02bebaa | ||
|
|
94aa309910 | ||
|
|
499a0a782a | ||
|
|
1e5a531a83 | ||
|
|
3e6a4073c4 | ||
|
|
e7cb6abd1f | ||
|
|
abfd8841a5 | ||
|
|
5e385fa33b | ||
|
|
95688c7e30 | ||
|
|
b041d3e70e | ||
|
|
0e91cddab9 | ||
|
|
d3856693ce | ||
|
|
40f36104f3 | ||
|
|
7215edb784 | ||
|
|
189be7ce69 | ||
|
|
28f10ffc25 | ||
|
|
be015320de | ||
|
|
a37d53b2e7 | ||
|
|
f43de11121 | ||
|
|
4c1129188b | ||
|
|
34e04f5251 | ||
|
|
b613d65b36 | ||
|
|
66aec63f6b | ||
|
|
5b0d18bb3b | ||
|
|
1c5b43c218 | ||
|
|
c78cfb9fcf | ||
|
|
927d4dd06f | ||
|
|
afb75ef75a | ||
|
|
92181866a4 | ||
|
|
c97805c7f1 | ||
|
|
c20a139e58 | ||
|
|
4287d1032f | ||
|
|
8b784d7c10 | ||
|
|
8895f6420f | ||
|
|
bb10ed5b7d | ||
|
|
9dc315dbf3 | ||
|
|
677531531f | ||
|
|
70c89b14a9 | ||
|
|
7f7c94e0d5 | ||
|
|
e6f09e42a1 | ||
|
|
f0419b7502 | ||
|
|
f01072eb11 | ||
|
|
c88102d6cc | ||
|
|
847a2994f9 | ||
|
|
ab186c0608 | ||
|
|
349ae8ed27 | ||
|
|
0066b858d6 | ||
|
|
e12e720a99 | ||
|
|
c17f2e2560 | ||
|
|
d75bf235bb | ||
|
|
881d1e9594 | ||
|
|
45a443989a | ||
|
|
7880fb402a | ||
|
|
ac2f8c9141 | ||
|
|
e36e774382 | ||
|
|
b1be2dfbf4 | ||
|
|
32f3a11bf7 | ||
|
|
7d0c72f92e | ||
|
|
27e0e12595 | ||
|
|
f6ae6b3658 | ||
|
|
9e1d633244 | ||
|
|
6b28e72686 | ||
|
|
dfd3a06600 | ||
|
|
2c35a6f0e1 | ||
|
|
f956558656 | ||
|
|
32fa7006ff | ||
|
|
95acf71dbf | ||
|
|
5640c27cec | ||
|
|
a7c5e4f317 | ||
|
|
274682e736 | ||
|
|
b4b6ab2667 | ||
|
|
bbe9dd6760 | ||
|
|
2aa7adb3bd | ||
|
|
fb7e671c26 | ||
|
|
7420dba0c9 | ||
|
|
9a059bdce4 | ||
|
|
50c7269315 | ||
|
|
b4434a369b | ||
|
|
1c945ebfbf | ||
|
|
20d0915a03 | ||
|
|
21ee94739b | ||
|
|
9ebb894694 | ||
|
|
483db08057 | ||
|
|
3a557998d0 | ||
|
|
c8322349a0 | ||
|
|
75b993bc6b | ||
|
|
b9db83a741 | ||
|
|
5bbb65b569 | ||
|
|
974eedc4dd | ||
|
|
c38c95dab5 | ||
|
|
c3a3446baa | ||
|
|
443413c03e | ||
|
|
0c56f420d5 | ||
|
|
f66bcb22c4 | ||
|
|
b44d59a303 | ||
|
|
dbe382f91e | ||
|
|
1d4ec9cd71 | ||
|
|
36f88b198c | ||
|
|
e2ca80a33f | ||
|
|
c08f981224 | ||
|
|
846f59974c | ||
|
|
5e368f486a | ||
|
|
42eed07dfd | ||
|
|
fcd647832c | ||
|
|
06d30f0182 | ||
|
|
c6c5b2e682 | ||
|
|
5431a84f37 | ||
|
|
764c6f0086 | ||
|
|
7f48c5c0e5 | ||
|
|
bd66cda0ee | ||
|
|
030ddbe12f | ||
|
|
60e3b21596 | ||
|
|
647e0236bb | ||
|
|
83c0b8b96e | ||
|
|
4d2f1ca10e | ||
|
|
678a617b0b | ||
|
|
b88d78a7e5 | ||
|
|
3d4092ee3e | ||
|
|
0306a79a37 | ||
|
|
539503f766 | ||
|
|
e06022e4d4 | ||
|
|
afb93eda2c | ||
|
|
6d2f5fcb60 | ||
|
|
1fb37aec25 | ||
|
|
5174662fe8 | ||
|
|
e47bafce29 | ||
|
|
7cf68a4b68 | ||
|
|
694d5d92b7 | ||
|
|
83d9d98ba3 | ||
|
|
cf3d0fe78d | ||
|
|
56aaf52430 | ||
|
|
40696ddea7 | ||
|
|
38d2dc8c8e | ||
|
|
69346c5b3e | ||
|
|
a2aa527f50 | ||
|
|
b2ae40c8c8 | ||
|
|
11498dcc7f | ||
|
|
140d5242cf | ||
|
|
e3dff56479 | ||
|
|
0fb7666b97 | ||
|
|
5c06de6abc | ||
|
|
582a609d27 | ||
|
|
ec3d25e64e | ||
|
|
740c7510ea | ||
|
|
c9f6c707ac | ||
|
|
667eee07b1 | ||
|
|
deba38ab60 | ||
|
|
25e44e54fb | ||
|
|
62a2341ab4 | ||
|
|
53b465b7bb | ||
|
|
fc6a3282ad | ||
|
|
cecd1ccc96 | ||
|
|
439987c149 | ||
|
|
61279ac119 | ||
|
|
ca2fbf5cdf | ||
|
|
d3129224bd | ||
|
|
57625b26c9 | ||
|
|
e345009e0a | ||
|
|
41f5071d7f | ||
|
|
623969be82 | ||
|
|
d106037f42 | ||
|
|
a9f1b3eea9 | ||
|
|
a1f1067063 | ||
|
|
f57dda5d09 | ||
|
|
93acb8b163 | ||
|
|
4f32ab4421 | ||
|
|
c52736372a | ||
|
|
eca11bc064 | ||
|
|
093fd2d638 | ||
|
|
194fb44fb5 | ||
|
|
0c032d69ee | ||
|
|
b2219d879f | ||
|
|
304cf9d797 | ||
|
|
29963a04fc | ||
|
|
dff80d8276 | ||
|
|
f33bb0d73f | ||
|
|
be09dd41fa | ||
|
|
36b12b645b | ||
|
|
bea15771b9 | ||
|
|
8c2cbce4a4 | ||
|
|
9674f4e739 | ||
|
|
137952af73 | ||
|
|
66dcb1020a | ||
|
|
829d19dfc2 | ||
|
|
c73159d2d0 | ||
|
|
4159fae8c9 | ||
|
|
bff045fff2 | ||
|
|
3090e7c163 | ||
|
|
38798aec73 | ||
|
|
bc7a69044b | ||
|
|
ee6512567e | ||
|
|
1b7ded4560 | ||
|
|
e9abe63b47 | ||
|
|
b70bf81d6c | ||
|
|
410fddbf7f | ||
|
|
c0c9026da6 | ||
|
|
f76e534b64 | ||
|
|
468148ceb2 | ||
|
|
cc69cac29e | ||
|
|
19d2a4d1cd | ||
|
|
a7dcdc8df2 | ||
|
|
7815d5ac5d | ||
|
|
23051db54a | ||
|
|
f51434880f | ||
|
|
87d5b4d3af | ||
|
|
dd335ac75b | ||
|
|
16d5e5f906 | ||
|
|
42114a3680 | ||
|
|
e7adaecb0f | ||
|
|
9818f3df46 | ||
|
|
ca832a01cb | ||
|
|
aaa2b204ba | ||
|
|
78bf9e5993 | ||
|
|
8be0296fc1 | ||
|
|
26cd741c04 | ||
|
|
bf655b3327 | ||
|
|
1793b37adc | ||
|
|
d0ffe85abb | ||
|
|
f9f7dcfc58 | ||
|
|
f06257e7ff | ||
|
|
e490f0bce6 | ||
|
|
770c7173ec | ||
|
|
661ab4867b | ||
|
|
9ee3b5aae6 | ||
|
|
d202256c30 | ||
|
|
b8856d4ef7 | ||
|
|
e1294ac210 | ||
|
|
b0edd2d137 | ||
|
|
0d0e9bc953 | ||
|
|
2576291d9f | ||
|
|
d2aab87faa | ||
|
|
c2509b462c | ||
|
|
0e378be769 | ||
|
|
2785eaab21 | ||
|
|
8a10fd1547 | ||
|
|
8f8ed817fb | ||
|
|
7a150254fe | ||
|
|
9612a4a781 | ||
|
|
249b233dc2 | ||
|
|
c4d4a9b47b | ||
|
|
a55e991bfa | ||
|
|
610276f66b | ||
|
|
de99aabf7f | ||
|
|
40a0a0083f | ||
|
|
56ecd2ac14 | ||
|
|
4617d58b6a | ||
|
|
98aeff2f3e | ||
|
|
f2239decca | ||
|
|
36bd25a9cc | ||
|
|
933ae663f0 | ||
|
|
a08674f708 | ||
|
|
7fe0855932 | ||
|
|
d7594c4a1c | ||
|
|
d9c8fa6043 | ||
|
|
4140d3084e | ||
|
|
93d3c9c657 | ||
|
|
3433f1224a | ||
|
|
95ac686f04 | ||
|
|
ae8d11825a | ||
|
|
ece796432a | ||
|
|
995ae21075 | ||
|
|
4a2d52717c | ||
|
|
c0a07a6144 | ||
|
|
b14560c07d | ||
|
|
5de7d7f882 | ||
|
|
a4ae3b223c | ||
|
|
383571ef05 | ||
|
|
7e5459cc62 | ||
|
|
caa8d9c0ed | ||
|
|
df887dc0e9 | ||
|
|
262e3bbee2 | ||
|
|
87463c7e70 | ||
|
|
2dc3e9af5e | ||
|
|
d1de99d48d | ||
|
|
db87a06cfd | ||
|
|
fab38c1f4e | ||
|
|
298dbfb0e0 | ||
|
|
b978517945 | ||
|
|
5c55449a87 | ||
|
|
78425d1947 | ||
|
|
55529eb493 | ||
|
|
06b2d907b6 | ||
|
|
f54d96d916 | ||
|
|
2c3da88b44 | ||
|
|
a90b7a65de | ||
|
|
7ef0a5a550 | ||
|
|
5433ea0762 | ||
|
|
7162fd61fc | ||
|
|
d4271cf618 | ||
|
|
cc7dbb19a5 | ||
|
|
5381a23140 | ||
|
|
7bcffb9424 | ||
|
|
2fde4767a0 | ||
|
|
2f6b0861d9 | ||
|
|
c83eeefeb2 | ||
|
|
807227911a | ||
|
|
db71c89e35 | ||
|
|
8b29723317 | ||
|
|
bef3ebf9cc | ||
|
|
061e021cd4 | ||
|
|
55728fe332 | ||
|
|
b1b04c7e35 | ||
|
|
5b86a8d7c9 | ||
|
|
44a7a5e692 | ||
|
|
da33c80735 | ||
|
|
25935abf3a | ||
|
|
93e7914a86 | ||
|
|
36231b88db | ||
|
|
14c1ecd515 | ||
|
|
dd38e11a5d | ||
|
|
9572bdcbf9 | ||
|
|
9ad0efd85b | ||
|
|
399b799002 | ||
|
|
48fbedd8ee | ||
|
|
a85dba8b49 | ||
|
|
64240bf70a | ||
|
|
cd06011b5e | ||
|
|
4d29b74c29 | ||
|
|
e5a12ade90 | ||
|
|
981fb7f330 | ||
|
|
7851cb81bb | ||
|
|
4e586bf31f | ||
|
|
9860f1eb68 | ||
|
|
9397f38929 | ||
|
|
540943109b | ||
|
|
73dee79a4c | ||
|
|
894f8b8c77 | ||
|
|
056e24a653 | ||
|
|
4045bbb1bc | ||
|
|
2634557def | ||
|
|
2af3d5b8b1 | ||
|
|
a9ea1b84cc | ||
|
|
10fc2495cd | ||
|
|
e9f5e593ce | ||
|
|
eec98c9674 | ||
|
|
0fddeebbc6 | ||
|
|
125e9312c1 | ||
|
|
e6a305026d | ||
|
|
f5cf7c0ca7 | ||
|
|
4a903371ac | ||
|
|
13777c8773 | ||
|
|
b38b749438 | ||
|
|
ff68a9f508 | ||
|
|
4767ba6b9c | ||
|
|
d7467d9b8e | ||
|
|
ab11081276 | ||
|
|
1e280928d8 | ||
|
|
e245689b85 | ||
|
|
bd31694850 | ||
|
|
97437838f8 | ||
|
|
2c226a9c83 | ||
|
|
7a06721e16 | ||
|
|
ae0dd7b9c0 | ||
|
|
28d83c1e11 | ||
|
|
589d49af30 | ||
|
|
9283e367b1 | ||
|
|
37fa2f8431 | ||
|
|
a3ffb80344 | ||
|
|
5c0ffae67a | ||
|
|
a216af40dc | ||
|
|
51e2fffe7e | ||
|
|
b6af5dcb3a | ||
|
|
2aa943bef2 | ||
|
|
27ea4f76f0 | ||
|
|
1a4b6a66ae | ||
|
|
cf14b32355 | ||
|
|
707c5cba41 | ||
|
|
c803f92104 | ||
|
|
96d5d025dc | ||
|
|
91061235d8 | ||
|
|
105ce757d0 | ||
|
|
031b3a9f51 | ||
|
|
1fa9ea7a0e | ||
|
|
641ede20f3 | ||
|
|
b5051008e3 | ||
|
|
4eabb97821 | ||
|
|
76bf1bde87 | ||
|
|
dfe5591822 | ||
|
|
b27d86c1a5 | ||
|
|
c7b064c751 | ||
|
|
06a3d0e500 | ||
|
|
1ffe3c4813 | ||
|
|
a8c99d7594 | ||
|
|
144e13245a | ||
|
|
4ea0c7e875 | ||
|
|
d38bbd9603 | ||
|
|
881a502cbc | ||
|
|
cbecd918fc | ||
|
|
ff0044229a | ||
|
|
175924d705 | ||
|
|
26c138908a | ||
|
|
fd93a10376 | ||
|
|
486b3a1f44 | ||
|
|
cd63722e5e | ||
|
|
e75917a4d3 | ||
|
|
b288bcbc18 | ||
|
|
5b2b104e37 | ||
|
|
e9f2216f84 | ||
|
|
7d7d098efa | ||
|
|
59494833b7 | ||
|
|
ddc059713d | ||
|
|
009703fabe | ||
|
|
b3b5f1b584 | ||
|
|
7771f30270 | ||
|
|
8a26dddd08 | ||
|
|
98b4c1388e | ||
|
|
6d89f2160d | ||
|
|
3e8859b8dd | ||
|
|
27babe6677 | ||
|
|
2a6a3e624d | ||
|
|
6ff42d1627 | ||
|
|
7188cfe85a | ||
|
|
cccdba57fe | ||
|
|
b3bd502028 | ||
|
|
423b33e088 | ||
|
|
edb63380ed | ||
|
|
7175bb7b47 | ||
|
|
c817916e0f | ||
|
|
426b48bd13 | ||
|
|
88ba714b59 | ||
|
|
795fdd477c | ||
|
|
6f021049ab | ||
|
|
bbdc137f64 | ||
|
|
843974d810 | ||
|
|
b97f025ea7 | ||
|
|
670a32271a | ||
|
|
71a33f2f02 | ||
|
|
f477a215cf | ||
|
|
12b09cf963 | ||
|
|
bedd7b6f41 | ||
|
|
ee5ae22779 | ||
|
|
316f0722d8 | ||
|
|
34cb30bb39 | ||
|
|
84ec05a257 | ||
|
|
78bdfefc66 | ||
|
|
33899405ba | ||
|
|
b3fd720668 | ||
|
|
dc7a447baf | ||
|
|
138b56a429 | ||
|
|
4699a37b4b | ||
|
|
940e21e74f | ||
|
|
b6f330cc91 | ||
|
|
f388a46484 | ||
|
|
a66d023f84 | ||
|
|
188cad3a67 | ||
|
|
4d5bdf6b6f | ||
|
|
96810788fc | ||
|
|
2f356fe26d | ||
|
|
ab9e2729cd | ||
|
|
203f105974 | ||
|
|
972b8e110f | ||
|
|
31d0b8acbf | ||
|
|
0152560fd8 | ||
|
|
e78214c38d | ||
|
|
79ca759774 | ||
|
|
5d1e5ca2ff | ||
|
|
8d13ae9e1e | ||
|
|
b763df5730 | ||
|
|
a237388bd4 | ||
|
|
610f3525a2 | ||
|
|
fff692bd0c | ||
|
|
a2fff64bd8 | ||
|
|
c00074e40b | ||
|
|
93319402cb | ||
|
|
4d2d359b06 | ||
|
|
0cc4a7d238 | ||
|
|
026c6fac2e | ||
|
|
d56ac18585 | ||
|
|
e90d8dcdb5 | ||
|
|
1a1c207a97 | ||
|
|
9b1203185d | ||
|
|
3214af53b7 | ||
|
|
ec6b58d7d4 | ||
|
|
0d888c9eeb | ||
|
|
f957f1d2bb | ||
|
|
730344a201 | ||
|
|
c5e74ca5e0 | ||
|
|
3216c29766 | ||
|
|
db5babf012 | ||
|
|
da147aacd4 | ||
|
|
8c80c1d077 | ||
|
|
7ff646d044 | ||
|
|
cdc1e024f1 | ||
|
|
b9dec2f714 | ||
|
|
0b296cb271 | ||
|
|
e62cca40ac | ||
|
|
170ae3602b | ||
|
|
96349be350 | ||
|
|
62e4828b0d | ||
|
|
0d58a20d70 | ||
|
|
448288834a | ||
|
|
c0fc258848 | ||
|
|
6f1da7ad1f | ||
|
|
c0e2b6ac4d | ||
|
|
99ebce0462 | ||
|
|
9831629430 | ||
|
|
e0ce5b7d12 | ||
|
|
e757bbc1b2 | ||
|
|
f2d90fac26 | ||
|
|
a33e150312 | ||
|
|
e5e9a14de4 | ||
|
|
07311579af | ||
|
|
a517b7fb00 | ||
|
|
7474e7e7bb | ||
|
|
7a8ecf7377 | ||
|
|
def97afd9b | ||
|
|
6ba41af6dc | ||
|
|
a88b35f919 | ||
|
|
a0cf2ea56b | ||
|
|
75c4b4f234 | ||
|
|
37177f1226 | ||
|
|
18fb27d2f7 | ||
|
|
ee054c3181 | ||
|
|
594a3a1321 | ||
|
|
fca72c2b95 | ||
|
|
4048f466c2 | ||
|
|
5a28bbbc9b | ||
|
|
55294701f0 | ||
|
|
b36ddfb3c3 | ||
|
|
faef85b78f | ||
|
|
06c8f5de32 | ||
|
|
eb6af97b42 | ||
|
|
601e94d370 | ||
|
|
640ff152cc | ||
|
|
de19cc8afe | ||
|
|
214f852a98 | ||
|
|
c6b684df89 | ||
|
|
cb3efb157f | ||
|
|
17df48f9fa | ||
|
|
728d87028b | ||
|
|
131feabafe | ||
|
|
a6cf73b6d1 | ||
|
|
1d7fb0e43c | ||
|
|
bf11eacf5a | ||
|
|
513c29d349 | ||
|
|
b68f9f157c | ||
|
|
6b9b98ffdd | ||
|
|
5f7b4a9434 | ||
|
|
8e7d110a7a | ||
|
|
782053a6ec | ||
|
|
fdc72c27b6 | ||
|
|
8d502d2cb7 | ||
|
|
1df3065884 | ||
|
|
cc2ff8e3cb | ||
|
|
bce821dee9 | ||
|
|
9e67efbd1b | ||
|
|
5f081d038e | ||
|
|
d434925f0b | ||
|
|
1b62a57e7c | ||
|
|
13447f0b4f | ||
|
|
327810390e | ||
|
|
f8071ce942 | ||
|
|
2f858e29cb | ||
|
|
1eaecf7568 | ||
|
|
e83747e7ed | ||
|
|
3260d9376e | ||
|
|
827e825e53 | ||
|
|
0521ae4c75 | ||
|
|
3deb5dbb9b | ||
|
|
d58c3bd3d1 | ||
|
|
298bfa81b6 | ||
|
|
a9d1d1a63a | ||
|
|
e5c2a7f176 | ||
|
|
da05003a5c | ||
|
|
b9dfa1aafe | ||
|
|
a57410133a | ||
|
|
f26e646cfc | ||
|
|
2a755b0e65 | ||
|
|
5fdcb322c8 | ||
|
|
76afc2b3ff | ||
|
|
6eb4f7e4a1 | ||
|
|
80412a7c2b | ||
|
|
478b2cb7a2 | ||
|
|
bdc00a152c | ||
|
|
c7cec1b2f1 | ||
|
|
178f3cd4a3 | ||
|
|
3340d39f67 | ||
|
|
5e7c39e42c | ||
|
|
ab479ab885 | ||
|
|
65081d995e | ||
|
|
05b2692eb5 | ||
|
|
ca7b8e589e | ||
|
|
56c325b526 | ||
|
|
732402159c | ||
|
|
1ef3b9ed13 | ||
|
|
ef43a76b0b | ||
|
|
4003a8023c | ||
|
|
102205ff71 | ||
|
|
b736e5d971 | ||
|
|
5720009e29 | ||
|
|
04e2d1a89a | ||
|
|
bc0525589c | ||
|
|
122e8ac9d6 | ||
|
|
dc7b110da2 | ||
|
|
37259baf08 | ||
|
|
d87d095fe9 | ||
|
|
44a1baa41f | ||
|
|
a1bc60145c | ||
|
|
802919e6ea | ||
|
|
1f674b5b86 | ||
|
|
53b15f4507 | ||
|
|
a5e2fa80e8 | ||
|
|
f10f62cebd | ||
|
|
37ac4d30e5 | ||
|
|
0ac43cefa2 | ||
|
|
4c60173b02 | ||
|
|
dbcdc22b26 | ||
|
|
726596d568 | ||
|
|
3e3f223bb2 | ||
|
|
17eb760928 | ||
|
|
4cbfbdd621 | ||
|
|
aeb8e89b69 | ||
|
|
0759e1ece2 | ||
|
|
fd7b2b7c4b | ||
|
|
7ef8f9ac13 | ||
|
|
dbb6c2bd9f | ||
|
|
b18bd735c9 | ||
|
|
b7752cc8a2 | ||
|
|
e8bc88eace | ||
|
|
19a4a99e76 | ||
|
|
bc213888e8 | ||
|
|
c784b46a5e | ||
|
|
1c9ba5b512 | ||
|
|
3d99ea5cbf | ||
|
|
28dc5a5b8c | ||
|
|
dcf23d0952 | ||
|
|
e597ecfe78 | ||
|
|
1c75ac12e8 | ||
|
|
28c4046300 | ||
|
|
762b5444f5 | ||
|
|
a0e34c3a21 | ||
|
|
504892ddb9 | ||
|
|
5927bf8149 | ||
|
|
45069604e1 | ||
|
|
b7f42f47a1 | ||
|
|
2175562b9a | ||
|
|
311ae5c4c5 | ||
|
|
8f29df541f | ||
|
|
80e61206fd | ||
|
|
354d15cbf1 | ||
|
|
12c5100bc8 | ||
|
|
366db1623b | ||
|
|
88457d726b | ||
|
|
ac754f86f3 | ||
|
|
4bb1024041 | ||
|
|
a0d97ff7ed | ||
|
|
6a1a83cc2b | ||
|
|
abf0f7111d | ||
|
|
ef82489040 | ||
|
|
49474c6fc8 | ||
|
|
7ee0dc48a7 | ||
|
|
ca531f0c13 | ||
|
|
e1ef1efdb5 | ||
|
|
c8c393eff9 | ||
|
|
6fd80cd16f | ||
|
|
6f7a3ed031 | ||
|
|
be597ed467 | ||
|
|
a5267bcb5b | ||
|
|
c512693b9d | ||
|
|
95b19864d3 | ||
|
|
db6758f7f7 | ||
|
|
f11f3fdee1 | ||
|
|
497d055b63 | ||
|
|
8f9ecdcfb5 | ||
|
|
fb47b28318 | ||
|
|
6fa72cf912 | ||
|
|
df6fa0be24 | ||
|
|
edb7cfc08d | ||
|
|
559c132d17 | ||
|
|
4e006e9481 | ||
|
|
717a6b6d07 | ||
|
|
04c101018a | ||
|
|
d6a298cffd | ||
|
|
018755516b | ||
|
|
31e17daa34 | ||
|
|
0748743fe0 | ||
|
|
0a7ff53fc7 | ||
|
|
da9ca18fe3 | ||
|
|
d292ab72d2 | ||
|
|
9c77af0d67 | ||
|
|
03f3d295c9 | ||
|
|
9aa5ca022d | ||
|
|
35e2e1848a | ||
|
|
087ee35ece | ||
|
|
399809ee6b | ||
|
|
cf6b12842f | ||
|
|
702c138f44 | ||
|
|
b0f0066f28 | ||
|
|
47c9a1d80f | ||
|
|
239f65d04d | ||
|
|
2cd534526f | ||
|
|
604ecbbf95 | ||
|
|
5e6191f235 | ||
|
|
026f269bdf | ||
|
|
7970955c00 | ||
|
|
3a0ea03a9c | ||
|
|
4ea07940f8 | ||
|
|
a8ac42037b | ||
|
|
78a45fc92d | ||
|
|
a6a12335f1 | ||
|
|
d82c1427f7 | ||
|
|
f2c766ddaf | ||
|
|
33aefb69f4 | ||
|
|
2751624b2b | ||
|
|
fc55267dc3 | ||
|
|
9ea1bb492f | ||
|
|
42c4b95df1 | ||
|
|
55325a0812 | ||
|
|
86bfc0a7f9 | ||
|
|
166fce793f | ||
|
|
df53489498 | ||
|
|
d050f48d4f | ||
|
|
d204418530 | ||
|
|
a4d21586d0 | ||
|
|
bf5c7a41d6 | ||
|
|
73cae2e726 | ||
|
|
019a83bd83 | ||
|
|
826b14b54f | ||
|
|
8a81d59240 | ||
|
|
4581e1daf9 | ||
|
|
1d619b0954 | ||
|
|
6b666bf304 | ||
|
|
cbb784637a | ||
|
|
175dc33b01 | ||
|
|
aa1b98aef8 | ||
|
|
c842a1e8d4 | ||
|
|
7e8be87da2 | ||
|
|
97b9bd0593 | ||
|
|
389865ba13 | ||
|
|
bdaceedc91 | ||
|
|
2c910b0778 | ||
|
|
f01721ce64 | ||
|
|
35b16d421e | ||
|
|
147def5059 | ||
|
|
bf16dd2cf8 | ||
|
|
24feace60b | ||
|
|
3ab8a8e25f | ||
|
|
e96c7bf987 | ||
|
|
e7c39cb53f | ||
|
|
a8aca3ad0f | ||
|
|
b531f6ab8b | ||
|
|
bd83d995fa | ||
|
|
7962303c72 | ||
|
|
991056a861 | ||
|
|
369a1a8ad9 | ||
|
|
b8e7b9c8b3 | ||
|
|
df40bafcfe | ||
|
|
0cd8ac6754 | ||
|
|
ad416ca14f | ||
|
|
70784517e4 | ||
|
|
2c3dc6ceef | ||
|
|
db935b20a7 | ||
|
|
a1fd0318f1 | ||
|
|
c2151c1b59 | ||
|
|
8f729bba41 | ||
|
|
08bf0b6d4d | ||
|
|
1ff30c5e54 | ||
|
|
80e7fb9020 | ||
|
|
1bd0106c2b | ||
|
|
6c59192340 | ||
|
|
29c1498842 | ||
|
|
75c12e8966 | ||
|
|
23291d4627 | ||
|
|
8b89767907 | ||
|
|
7bc43b4fe8 | ||
|
|
0aaf4c1f32 | ||
|
|
16394e6dbd | ||
|
|
3b531f863d | ||
|
|
0bc1a6a22a | ||
|
|
6dac9f769a | ||
|
|
5871ae1a59 | ||
|
|
0a9329ec56 | ||
|
|
00e34bb6fe | ||
|
|
75777dafc6 | ||
|
|
85ca07c521 | ||
|
|
b781e5cc88 | ||
|
|
13313028b5 | ||
|
|
0bc7c452c3 | ||
|
|
b549003054 | ||
|
|
2ee425bdf1 | ||
|
|
fe6160663a | ||
|
|
6549e6136c | ||
|
|
9b1668cbcd | ||
|
|
1c615b7fbf | ||
|
|
7c54012caa | ||
|
|
abee872931 | ||
|
|
1cbcec87d8 | ||
|
|
0f1960f22a | ||
|
|
fb0c000b54 | ||
|
|
87bb6e9995 | ||
|
|
45ceabf49e | ||
|
|
8202629f62 | ||
|
|
d3d15301f7 | ||
|
|
8817ade510 | ||
|
|
4423bfdaa1 | ||
|
|
56c766c7b8 | ||
|
|
f8d2f44f82 | ||
|
|
d86e736b33 | ||
|
|
e2db15ed4d | ||
|
|
d5af131144 | ||
|
|
1401e0ab5a | ||
|
|
49817ee0fa | ||
|
|
e4e5cab60f | ||
|
|
bd6a3a633d | ||
|
|
3d5500e69b | ||
|
|
b5fc236d43 | ||
|
|
9915e560b2 | ||
|
|
4cf07f143c | ||
|
|
9c0994219e | ||
|
|
1287412383 | ||
|
|
0712207ff2 | ||
|
|
3e11a5200e | ||
|
|
723b470284 | ||
|
|
a267aad709 | ||
|
|
b1b318e282 | ||
|
|
31a8d35bb9 | ||
|
|
f5a63998ce | ||
|
|
921f568d2d | ||
|
|
f43ac8554c | ||
|
|
988a21e94d | ||
|
|
a7172d8782 | ||
|
|
cc8c23db85 | ||
|
|
a6d7852903 | ||
|
|
af88fb8af4 | ||
|
|
d16c710caa | ||
|
|
23d362757c | ||
|
|
ef7bea6d2d | ||
|
|
4d0fa60a7a | ||
|
|
e25fc2da88 | ||
|
|
5558e0c62f | ||
|
|
10315ed240 | ||
|
|
754fb2397e | ||
|
|
df2d144590 | ||
|
|
432e47032e | ||
|
|
507d40b6f5 | ||
|
|
97eb814f21 | ||
|
|
0ef80e6d3e | ||
|
|
b651b5cb48 | ||
|
|
02d95e90b4 | ||
|
|
99e160686a | ||
|
|
fc9ada5f18 | ||
|
|
ce3c084ea1 | ||
|
|
ab24796316 | ||
|
|
aa2ee060f1 | ||
|
|
66e47990ac | ||
|
|
bd9f7bda29 | ||
|
|
b002cf3031 | ||
|
|
77407f0879 | ||
|
|
ff4c76e3a2 | ||
|
|
533e0fb10d | ||
|
|
c5bc3e27a8 | ||
|
|
fad0398a48 | ||
|
|
5ce519aef9 | ||
|
|
a0719275e6 | ||
|
|
01a2fc6b75 | ||
|
|
c232983e63 | ||
|
|
fe956d4617 | ||
|
|
fee8838e7b | ||
|
|
0996f8cccb |
@@ -8,3 +8,7 @@
|
||||
**/dist/**
|
||||
**/node_modules
|
||||
**/temp
|
||||
playwright.config.ts
|
||||
jest.config.js
|
||||
test/live-preview/next-app
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
72
.eslintrc.cjs
Normal file
72
.eslintrc.cjs
Normal file
@@ -0,0 +1,72 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: ['@payloadcms'],
|
||||
ignorePatterns: ['README.md', 'packages/**/*.spec.ts'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['packages/**'],
|
||||
plugins: ['payload'],
|
||||
rules: {
|
||||
'payload/no-jsx-import-statements': 'warn',
|
||||
'payload/no-relative-monorepo-imports': 'error',
|
||||
'payload/no-imports-from-exports-dir': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['scripts/**'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'no-console': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
extends: ['plugin:@typescript-eslint/disable-type-checked'],
|
||||
files: ['*.js', '*.cjs', '*.json', '*.md', '*.yml', '*.yaml'],
|
||||
},
|
||||
{
|
||||
files: ['packages/eslint-config-payload/**'],
|
||||
rules: {
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['templates/vercel-postgres/**'],
|
||||
rules: {
|
||||
'no-restricted-exports': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['package.json', 'tsconfig.json'],
|
||||
rules: {
|
||||
'perfectionist/sort-array-includes': 'off',
|
||||
'perfectionist/sort-astro-attributes': 'off',
|
||||
'perfectionist/sort-classes': 'off',
|
||||
'perfectionist/sort-enums': 'off',
|
||||
'perfectionist/sort-exports': 'off',
|
||||
'perfectionist/sort-imports': 'off',
|
||||
'perfectionist/sort-interfaces': 'off',
|
||||
'perfectionist/sort-jsx-props': 'off',
|
||||
'perfectionist/sort-keys': 'off',
|
||||
'perfectionist/sort-maps': 'off',
|
||||
'perfectionist/sort-named-exports': 'off',
|
||||
'perfectionist/sort-named-imports': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
'perfectionist/sort-svelte-attributes': 'off',
|
||||
'perfectionist/sort-union-types': 'off',
|
||||
'perfectionist/sort-vue-attributes': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname,
|
||||
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,
|
||||
EXPERIMENTAL_useProjectService: true,
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
root: true,
|
||||
}
|
||||
38
.eslintrc.js
38
.eslintrc.js
@@ -1,38 +0,0 @@
|
||||
module.exports = {
|
||||
extends: ['@payloadcms'],
|
||||
overrides: [
|
||||
{
|
||||
extends: ['plugin:@typescript-eslint/disable-type-checked'],
|
||||
files: ['*.js', '*.cjs', '*.json', '*.md', '*.yml', '*.yaml'],
|
||||
},
|
||||
{
|
||||
files: ['packages/eslint-config-payload/**'],
|
||||
rules: {
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['package.json', 'tsconfig.json'],
|
||||
rules: {
|
||||
'perfectionist/sort-array-includes': 'off',
|
||||
'perfectionist/sort-astro-attributes': 'off',
|
||||
'perfectionist/sort-classes': 'off',
|
||||
'perfectionist/sort-enums': 'off',
|
||||
'perfectionist/sort-exports': 'off',
|
||||
'perfectionist/sort-imports': 'off',
|
||||
'perfectionist/sort-interfaces': 'off',
|
||||
'perfectionist/sort-jsx-props': 'off',
|
||||
'perfectionist/sort-keys': 'off',
|
||||
'perfectionist/sort-maps': 'off',
|
||||
'perfectionist/sort-named-exports': 'off',
|
||||
'perfectionist/sort-named-imports': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
'perfectionist/sort-svelte-attributes': 'off',
|
||||
'perfectionist/sort-union-types': 'off',
|
||||
'perfectionist/sort-vue-attributes': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
root: true,
|
||||
}
|
||||
@@ -16,3 +16,6 @@ fb7d1be2f3325d076b7c967b1730afcef37922c2
|
||||
|
||||
# lint and format create-payload-app
|
||||
5fd3d430001efe86515262ded5e26f00c1451181
|
||||
|
||||
# 3.0 prettier & lint everywhere
|
||||
6789e61488a1d3de56f472ac3214faf344030005
|
||||
|
||||
56
.github/CODEOWNERS
vendored
56
.github/CODEOWNERS
vendored
@@ -1,50 +1,30 @@
|
||||
# Order matters. The last matching pattern takes precedence.
|
||||
|
||||
### Catch-all ###
|
||||
* @denolfe @jmikrut @DanRibbens
|
||||
.* @denolfe @jmikrut @DanRibbens
|
||||
### Package Exports ###
|
||||
/**/exports/ @denolfe @jmikrut
|
||||
|
||||
### Core ###
|
||||
/packages/payload/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/payload/src/uploads/ @denolfe
|
||||
/packages/payload/src/admin/ @jmikrut @jacobsfletch @JarrodMFlesch
|
||||
|
||||
### Adapters ###
|
||||
/packages/bundler-*/ @denolfe @jmikrut @DanRibbens @JarrodMFlesch
|
||||
/packages/db-*/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/richtext-*/ @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
|
||||
### Plugins ###
|
||||
/packages/plugin-*/ @denolfe @jmikrut @DanRibbens @jacobsfletch @JarrodMFlesch @AlessioGr
|
||||
### Packages ###
|
||||
/packages/richtext-*/ @AlessioGr
|
||||
/packages/plugin-cloud*/ @denolfe
|
||||
/packages/plugin-form-builder/ @jacobsfletch
|
||||
/packages/plugin-live-preview*/ @jacobsfletch
|
||||
/packages/plugin-nested-docs/ @jacobsfletch
|
||||
/packages/plugin-password-protection/ @jmikrut
|
||||
/packages/plugin-redirects/ @jacobsfletch
|
||||
/packages/plugin-search/ @jacobsfletch
|
||||
/packages/plugin-sentry/ @JessChowdhury
|
||||
/packages/plugin-seo/ @jacobsfletch
|
||||
/packages/plugin-stripe/ @jacobsfletch
|
||||
/packages/plugin-zapier/ @JarrodMFlesch
|
||||
|
||||
### Examples ###
|
||||
/examples/ @jacobsfletch
|
||||
/examples/testing/ @JarrodMFlesch
|
||||
/examples/email/ @JessChowdhury
|
||||
/examples/whitelabel/ @JessChowdhury
|
||||
/packages/email-*/ @denolfe
|
||||
/packages/storage-*/ @denolfe
|
||||
/packages/create-payload-app/ @denolfe
|
||||
/packages/eslint-*/ @denolfe
|
||||
|
||||
### Templates ###
|
||||
/templates/ @jacobsfletch
|
||||
/templates/blank/ @denolfe
|
||||
/templates/ @jacobsfletch @denolfe
|
||||
|
||||
### Misc ###
|
||||
/packages/create-payload-app/ @denolfe
|
||||
/packages/eslint-config-payload/ @denolfe
|
||||
/packages/payload-admin-bar/ @jacobsfletch
|
||||
### Build Files ###
|
||||
/**/package.json @denolfe
|
||||
/tsconfig.json @denolfe
|
||||
/**/tsconfig*.json @denolfe
|
||||
|
||||
/jest.config.js @denolfe
|
||||
/**/jest.config.js @denolfe
|
||||
|
||||
### Root ###
|
||||
/package.json @denolfe
|
||||
/scripts/ @denolfe
|
||||
/.husky/ @denolfe
|
||||
/.vscode/ @denolfe
|
||||
/.github/ @denolfe
|
||||
/.github/CODEOWNERS @denolfe
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/1.bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/1.bug_report.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Bug Report
|
||||
description: Create a bug report for Payload
|
||||
labels: ['possible-bug']
|
||||
labels: ['[possible-bug]']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
48
.github/actions/setup/action.yml
vendored
Normal file
48
.github/actions/setup/action.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Setup node and pnpm
|
||||
description: Configure the Node.js and pnpm versions
|
||||
|
||||
inputs:
|
||||
node-version:
|
||||
description: 'The Node.js version to use'
|
||||
required: true
|
||||
default: 18.20.2
|
||||
pnpm-version:
|
||||
description: 'The pnpm version to use'
|
||||
required: true
|
||||
default: 8.15.7
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
shell: bash
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ inputs.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ inputs.pnpm-version }}
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-store-
|
||||
pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- shell: bash
|
||||
run: pnpm install
|
||||
50
.github/workflows/label-author.yml
vendored
Normal file
50
.github/workflows/label-author.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: label-author
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
debug-context:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: View context attributes
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: console.log(context)
|
||||
|
||||
label-created-by:
|
||||
name: Label pr/issue on opening
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Tag with 'created-by'
|
||||
uses: actions/github-script@v7
|
||||
if: github.event.action == 'opened'
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const type = context.payload.pull_request ? 'pull_request' : 'issue';
|
||||
const association = context.payload[type].author_association;
|
||||
let label = ''
|
||||
if (association === 'MEMBER' || association === 'OWNER') {
|
||||
label = 'created-by: Payload team';
|
||||
} else if (association === 'CONTRIBUTOR') {
|
||||
label = 'created-by: Contributor';
|
||||
}
|
||||
|
||||
if (!label) return;
|
||||
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [label],
|
||||
});
|
||||
console.log('Added created-by: Payload team label');
|
||||
549
.github/workflows/main.yml
vendored
549
.github/workflows/main.yml
vendored
@@ -2,9 +2,25 @@ name: build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
push:
|
||||
branches: ['main']
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
|
||||
concurrency:
|
||||
# <workflow_name>-<branch_name>-<true || commit_sha if branch is protected>
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref_protected && github.sha || ''}}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NODE_VERSION: 18.20.2
|
||||
PNPM_VERSION: 8.15.7
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
@@ -15,27 +31,76 @@ jobs:
|
||||
needs_build: ${{ steps.filter.outputs.needs_build }}
|
||||
templates: ${{ steps.filter.outputs.templates }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
needs_build:
|
||||
- '.github/workflows/**'
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
templates:
|
||||
- 'templates/**'
|
||||
- name: Log all filter results
|
||||
run: |
|
||||
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
|
||||
echo "templates: ${{ steps.filter.outputs.templates }}"
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
core-build:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
needs_build:
|
||||
- '.github/workflows/**'
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
templates:
|
||||
- 'templates/**'
|
||||
- name: Log all filter results
|
||||
run: |
|
||||
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
|
||||
echo "templates: ${{ steps.filter.outputs.templates }}"
|
||||
|
||||
lint:
|
||||
if: >
|
||||
github.event_name == 'pull_request' && !contains(github.event.pull_request.title, 'no-lint') && !contains(github.event.pull_request.title, 'skip-lint')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 720
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-store-
|
||||
pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- run: pnpm install
|
||||
- name: Lint staged
|
||||
run: |
|
||||
git diff --name-only --diff-filter=d origin/${GITHUB_BASE_REF}...${GITHUB_SHA}
|
||||
npx lint-staged --diff="origin/${GITHUB_BASE_REF}...${GITHUB_SHA}"
|
||||
|
||||
build:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.needs_build == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -45,15 +110,19 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 25
|
||||
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
@@ -61,73 +130,148 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 720
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
pnpm-store-
|
||||
pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- run: pnpm run build:all
|
||||
env:
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
|
||||
- name: Cache build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
tests:
|
||||
tests-unit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Unit Tests
|
||||
run: pnpm test:unit
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8096
|
||||
|
||||
tests-int:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
database: [mongoose, postgres]
|
||||
database:
|
||||
- mongodb
|
||||
- postgres
|
||||
- postgres-custom-schema
|
||||
- postgres-uuid
|
||||
- supabase
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: payloadtests
|
||||
AWS_ENDPOINT_URL: http://127.0.0.1:4566
|
||||
AWS_ACCESS_KEY_ID: localstack
|
||||
AWS_SECRET_ACCESS_KEY: localstack
|
||||
AWS_REGION: us-east-1
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Start LocalStack
|
||||
run: pnpm docker:start
|
||||
|
||||
- name: Start PostgreSQL
|
||||
uses: CasperWA/postgresql-action@v1.2
|
||||
with:
|
||||
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
|
||||
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
|
||||
postgresql db: ${{ env.POSTGRES_DB }}
|
||||
postgresql user: ${{ env.POSTGRES_USER }}
|
||||
postgresql password: ${{ env.POSTGRES_PASSWORD }}
|
||||
if: matrix.database == 'postgres'
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- name: Install Supabase CLI
|
||||
uses: supabase/setup-cli@v1
|
||||
with:
|
||||
version: latest
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Initialize Supabase
|
||||
run: |
|
||||
supabase init
|
||||
supabase start
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Wait for PostgreSQL
|
||||
run: sleep 30
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- run: sleep 30
|
||||
- name: Configure PostgreSQL
|
||||
run: |
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE ROLE runner SUPERUSER LOGIN;"
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "SELECT version();"
|
||||
echo "POSTGRES_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" >> $GITHUB_ENV
|
||||
if: matrix.database == 'postgres'
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- name: Component Tests
|
||||
run: pnpm test:components
|
||||
- name: Configure PostgreSQL with custom schema
|
||||
run: |
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE SCHEMA custom;"
|
||||
if: matrix.database == 'postgres-custom-schema'
|
||||
|
||||
- name: Configure Supabase
|
||||
run: |
|
||||
echo "POSTGRES_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres" >> $GITHUB_ENV
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Integration Tests
|
||||
run: pnpm test:int
|
||||
@@ -138,63 +282,180 @@ jobs:
|
||||
|
||||
tests-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
part: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8]
|
||||
|
||||
# find test -type f -name 'e2e.spec.ts' | sort | xargs dirname | xargs -I {} basename {}
|
||||
suite:
|
||||
- _community
|
||||
- access-control
|
||||
- admin__e2e__1
|
||||
- admin__e2e__2
|
||||
- auth
|
||||
- field-error-states
|
||||
- fields-relationship
|
||||
- fields
|
||||
- fields__collections__Blocks
|
||||
- fields__collections__Array
|
||||
- fields__collections__Relationship
|
||||
- fields__collections__RichText
|
||||
- fields__collections__Lexical__e2e__main
|
||||
- fields__collections__Lexical__e2e__blocks
|
||||
- fields__collections__Date
|
||||
- fields__collections__Number
|
||||
- fields__collections__Point
|
||||
- fields__collections__Tabs
|
||||
- fields__collections__Text
|
||||
- fields__collections__Upload
|
||||
- live-preview
|
||||
- localization
|
||||
- i18n
|
||||
- plugin-cloud-storage
|
||||
- plugin-form-builder
|
||||
- plugin-nested-docs
|
||||
- plugin-seo
|
||||
- versions
|
||||
- uploads
|
||||
env:
|
||||
SUITE_NAME: ${{ matrix.suite }}
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: E2E Tests
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
retry_on: error
|
||||
max_attempts: 2
|
||||
timeout_minutes: 15
|
||||
command: pnpm test:e2e --part ${{ matrix.part }} --bail
|
||||
- name: Start LocalStack
|
||||
run: pnpm docker:start
|
||||
if: ${{ matrix.suite == 'plugin-cloud-storage' }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- name: Store Playwright's Version
|
||||
run: |
|
||||
# Extract the version number using a more targeted regex pattern with awk
|
||||
PLAYWRIGHT_VERSION=$(pnpm ls @playwright/test --depth=0 | awk '/@playwright\/test/ {print $2}')
|
||||
echo "Playwright's Version: $PLAYWRIGHT_VERSION"
|
||||
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache Playwright Browsers for Playwright's Version
|
||||
id: cache-playwright-browsers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
|
||||
|
||||
- name: Setup Playwright - Browsers and Dependencies
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
|
||||
run: pnpm exec playwright install --with-deps chromium
|
||||
|
||||
- name: Setup Playwright - Dependencies-only
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit == 'true'
|
||||
run: pnpm exec playwright install-deps chromium
|
||||
|
||||
- name: E2E Tests
|
||||
run: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e ${{ matrix.suite }}
|
||||
env:
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: results_${{ matrix.suite }}.json
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: test-results
|
||||
path: test-results/
|
||||
name: test-results-${{ matrix.suite }}
|
||||
path: test/test-results/
|
||||
if-no-files-found: ignore
|
||||
retention-days: 1
|
||||
|
||||
tests-type-generation:
|
||||
# Disabled until this is fixed: https://github.com/daun/playwright-report-summary/issues/156
|
||||
# - uses: daun/playwright-report-summary@v3
|
||||
# with:
|
||||
# report-file: results_${{ matrix.suite }}.json
|
||||
# report-tag: ${{ matrix.suite }}
|
||||
# job-summary: true
|
||||
|
||||
app-build-with-packed:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Start MongoDB
|
||||
uses: supercharge/mongodb-github-action@1.10.0
|
||||
with:
|
||||
mongodb-version: 6.0
|
||||
|
||||
- name: Pack and build app
|
||||
run: |
|
||||
set -ex
|
||||
pnpm run script:pack --dest templates/blank-3.0
|
||||
cd templates/blank-3.0
|
||||
cp .env.example .env
|
||||
ls -la
|
||||
pnpm add ./*.tgz --ignore-workspace
|
||||
pnpm install --ignore-workspace --no-frozen-lockfile
|
||||
cat package.json
|
||||
pnpm run build
|
||||
|
||||
tests-type-generation:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
@@ -205,86 +466,9 @@ jobs:
|
||||
- name: Generate GraphQL schema file
|
||||
run: pnpm dev:generate-graphql-schema graphql-schema-gen
|
||||
|
||||
build-packages:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pkg:
|
||||
- db-mongodb
|
||||
- db-postgres
|
||||
- bundler-webpack
|
||||
- bundler-vite
|
||||
- richtext-slate
|
||||
- richtext-lexical
|
||||
- live-preview
|
||||
- live-preview-react
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Build ${{ matrix.pkg }}
|
||||
run: pnpm turbo run build --filter=${{ matrix.pkg }}
|
||||
|
||||
plugins:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pkg:
|
||||
- create-payload-app
|
||||
- plugin-cloud
|
||||
- plugin-cloud-storage
|
||||
- plugin-form-builder
|
||||
- plugin-nested-docs
|
||||
- plugin-search
|
||||
- plugin-sentry
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Build ${{ matrix.pkg }}
|
||||
run: pnpm turbo run build --filter=${{ matrix.pkg }}
|
||||
|
||||
- name: Test ${{ matrix.pkg }}
|
||||
run: pnpm --filter ${{ matrix.pkg }} run test
|
||||
if: matrix.pkg != 'create-payload-app' # degit doesn't work within GitHub Actions
|
||||
|
||||
templates:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.templates == 'true' }}
|
||||
if: false # Disable until templates are updated for 3.0
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -295,20 +479,69 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Start MongoDB
|
||||
uses: supercharge/mongodb-github-action@1.10.0
|
||||
with:
|
||||
mongodb-version: 6.0
|
||||
|
||||
- name: Build Website
|
||||
- name: Build Template
|
||||
run: |
|
||||
cd templates/${{ matrix.template }}
|
||||
cp .env.example .env
|
||||
yarn install
|
||||
yarn build
|
||||
yarn generate:types
|
||||
|
||||
generated-templates:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Build all generated templates
|
||||
run: pnpm tsx ./scripts/build-generated-templates.ts
|
||||
|
||||
all-green:
|
||||
name: All Green
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- lint
|
||||
- build
|
||||
- tests-unit
|
||||
- tests-int
|
||||
- tests-e2e
|
||||
|
||||
steps:
|
||||
- if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}
|
||||
run: exit 1
|
||||
|
||||
103
.github/workflows/pr-title.yml
vendored
Normal file
103
.github/workflows/pr-title.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: pr-title
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: lint-pr-title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
id: lint_pr_title
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
types: |
|
||||
build
|
||||
chore
|
||||
ci
|
||||
docs
|
||||
feat
|
||||
fix
|
||||
perf
|
||||
refactor
|
||||
revert
|
||||
style
|
||||
test
|
||||
types
|
||||
scopes: |
|
||||
cpa
|
||||
db-\*
|
||||
db-mongodb
|
||||
db-postgres
|
||||
email-nodemailer
|
||||
eslint
|
||||
graphql
|
||||
live-preview
|
||||
live-preview-react
|
||||
next
|
||||
payload
|
||||
plugin-cloud
|
||||
plugin-cloud-storage
|
||||
plugin-form-builder
|
||||
plugin-nested-docs
|
||||
plugin-redirects
|
||||
plugin-relationship-object-ids
|
||||
plugin-search
|
||||
plugin-sentry
|
||||
plugin-seo
|
||||
plugin-stripe
|
||||
richtext-\*
|
||||
richtext-lexical
|
||||
richtext-slate
|
||||
storage-\*
|
||||
storage-azure
|
||||
storage-gcs
|
||||
storage-vercel-blob
|
||||
storage-s3
|
||||
translations
|
||||
ui
|
||||
templates
|
||||
examples(\/(\w|-)+)?
|
||||
deps
|
||||
|
||||
# Disallow uppercase letters at the beginning of the subject
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
doesn't start with an uppercase character.
|
||||
|
||||
- uses: marocchino/sticky-pull-request-comment@v2
|
||||
# When the previous steps fails, the workflow would stop. By adding this
|
||||
# condition you can continue the execution with the populated error message.
|
||||
if: always() && (steps.lint_pr_title.outputs.error_message != null)
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
message: |
|
||||
Pull Request titles must follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and have valid scopes.
|
||||
|
||||
${{ steps.lint_pr_title.outputs.error_message }}
|
||||
|
||||
```
|
||||
feat(ui): add Button component
|
||||
^ ^ ^
|
||||
| | |__ Subject
|
||||
| |_______ Scope
|
||||
|____________ Type
|
||||
```
|
||||
|
||||
# Delete a previous comment when the issue has been resolved
|
||||
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
delete: true
|
||||
36
.github/workflows/release-canary.yml
vendored
Normal file
36
.github/workflows/release-canary.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: release-canary
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
branches:
|
||||
- beta
|
||||
|
||||
env:
|
||||
NODE_VERSION: 18.20.2
|
||||
PNPM_VERSION: 8.15.7
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
|
||||
|
||||
jobs:
|
||||
release:
|
||||
permissions:
|
||||
id-token: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
pnpm-version: ${{ env.PNPM_VERSION }}
|
||||
- name: Load npm token
|
||||
run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
- name: Canary release script
|
||||
# dry run hard-coded to true for testing and no npm token provided
|
||||
run: pnpm tsx ./scripts/publish-canary.ts
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_CONFIG_PROVENANCE: true
|
||||
118
.gitignore
vendored
118
.gitignore
vendored
@@ -1,10 +1,28 @@
|
||||
coverage
|
||||
package-lock.json
|
||||
dist
|
||||
.idea
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
!/.idea/payload.iml
|
||||
|
||||
test-results
|
||||
.devcontainer
|
||||
.localstack
|
||||
/migrations
|
||||
.localstack
|
||||
.turbo
|
||||
|
||||
meta_client.json
|
||||
meta_server.json
|
||||
meta_index.json
|
||||
meta_shared.json
|
||||
|
||||
.turbo
|
||||
|
||||
# Ignore test directory media folder/files
|
||||
/media
|
||||
test/media
|
||||
/versions
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
@@ -230,119 +248,24 @@ GitHub.sublime-settings
|
||||
.history
|
||||
.ionide
|
||||
|
||||
### WebStorm ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### WebStorm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||
.idea/**/sonarlint/
|
||||
|
||||
# SonarQube Plugin
|
||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||
.idea/**/sonarIssues.xml
|
||||
|
||||
# Markdown Navigator plugin
|
||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||
.idea/**/markdown-navigator.xml
|
||||
.idea/**/markdown-navigator-enh.xml
|
||||
.idea/**/markdown-navigator/
|
||||
|
||||
# Cache file creation bug
|
||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||
.idea/$CACHE_FILE$
|
||||
|
||||
# CodeStream plugin
|
||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||
.idea/codestream.xml
|
||||
|
||||
# Azure Toolkit for IntelliJ plugin
|
||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||
.idea/**/azureSettings.xml
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
@@ -371,4 +294,5 @@ $RECYCLE.BIN/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
|
||||
/build
|
||||
/build
|
||||
.swc
|
||||
|
||||
82
.idea/payload.iml
generated
Normal file
82
.idea/payload.iml
generated
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/components" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/examples" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/media" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/next/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/next/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/fields" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-form-builder/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-sentry/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-stripe/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/templates" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/test/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/versions" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-slate/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-slate/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/email-nodemailer/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/email-nodemailer/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/email-resend/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/email-resend/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-vue/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-vue/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-form-builder/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-relationship-object-ids/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-relationship-object-ids/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-stripe/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-azure/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-azure/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-gcs/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-gcs/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-s3/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-s3/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-uploadthing/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-uploadthing/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-vercel-blob/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/storage-vercel-blob/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/translations/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/translations/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/ui/dist" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/runConfigurations/Run_Dev_Fields.xml
generated
Normal file
8
.idea/runConfigurations/Run_Dev_Fields.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="--no-deprecation fields" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
|
||||
<envs>
|
||||
<env name="NODE_OPTIONS" value="--no-deprecation" />
|
||||
</envs>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
8
.idea/runConfigurations/Run_Dev__community.xml
generated
Normal file
8
.idea/runConfigurations/Run_Dev__community.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="--no-deprecation _community" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
|
||||
<envs>
|
||||
<env name="NODE_OPTIONS" value="--no-deprecation" />
|
||||
</envs>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
9
.idea/runConfigurations/_template__of_JavaScriptTestRunnerJest.xml
generated
Normal file
9
.idea/runConfigurations/_template__of_JavaScriptTestRunnerJest.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="true" type="JavaScriptTestRunnerJest">
|
||||
<node-interpreter value="project" />
|
||||
<node-options value="--experimental-vm-modules --no-deprecation" />
|
||||
<envs />
|
||||
<scope-kind value="ALL" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1 +1 @@
|
||||
v18.17.1
|
||||
v18.20.2
|
||||
|
||||
@@ -9,3 +9,8 @@
|
||||
**/node_modules
|
||||
**/temp
|
||||
**/docs/**
|
||||
tsconfig.json
|
||||
packages/payload/*.js
|
||||
packages/payload/*.d.ts
|
||||
payload-types.ts
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
verbose: true,
|
||||
git: {
|
||||
requireCleanWorkingDir: false,
|
||||
commit: false,
|
||||
push: false,
|
||||
tag: false,
|
||||
},
|
||||
npm: {
|
||||
skipChecks: true,
|
||||
tag: 'beta',
|
||||
},
|
||||
hooks: {
|
||||
'before:init': ['pnpm install', 'pnpm clean', 'pnpm build'],
|
||||
},
|
||||
}
|
||||
24
.swcrc
Normal file
24
.swcrc
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/swcrc",
|
||||
"sourceMaps": "inline",
|
||||
"jsc": {
|
||||
"target": "esnext",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dts": true
|
||||
},
|
||||
"transform": {
|
||||
"react": {
|
||||
"runtime": "automatic",
|
||||
"pragmaFrag": "React.Fragment",
|
||||
"throwIfNamespace": true,
|
||||
"development": false,
|
||||
"useBuiltins": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
}
|
||||
}
|
||||
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@@ -1,3 +1,8 @@
|
||||
{
|
||||
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"ms-playwright.playwright"
|
||||
]
|
||||
}
|
||||
|
||||
91
.vscode/launch.json
vendored
91
.vscode/launch.json
vendored
@@ -3,12 +3,59 @@
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"configurations": [
|
||||
{
|
||||
"command": "pnpm run dev _community",
|
||||
"command": "pnpm generate:types",
|
||||
"name": "Generate Types CLI",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js _community",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Community",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js storage-uploadthing",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Uploadthing",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"envFile": "${workspaceFolder}/test/storage-uploadthing/.env"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js live-preview",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Live Preview",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/loader/init.js",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Loader",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"LOADER_TEST_FILE_PATH": "./dependency-test.js"
|
||||
// "LOADER_TEST_FILE_PATH": "../fields/config.ts"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js admin",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Admin",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js auth",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Auth",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev plugin-cloud-storage",
|
||||
"cwd": "${workspaceFolder}",
|
||||
@@ -20,49 +67,56 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev fields",
|
||||
"command": "node --no-deprecation test/dev.js collections-graphql",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev GraphQL",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js fields",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Fields",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev:postgres fields",
|
||||
"command": "node --no-deprecation test/dev.js versions",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Postgres",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"PAYLOAD_DATABASE": "postgres"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev versions",
|
||||
"command": "node --no-deprecation test/dev.js versions",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Versions",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev localization",
|
||||
"command": "node --no-deprecation test/dev.js localization",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Localization",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev uploads",
|
||||
"command": "node --no-deprecation test/dev.js uploads",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Uploads",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "PAYLOAD_BUNDLER=vite pnpm run dev fields",
|
||||
"command": "node --no-deprecation test/dev.js field-error-states",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Fields (Vite)",
|
||||
"name": "Run Dev Field Error States",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"NODE_ENV": "production"
|
||||
}
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run test:int live-preview",
|
||||
@@ -102,17 +156,6 @@
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "ts-node ./packages/payload/src/bin/index.ts generate:types",
|
||||
"env": {
|
||||
"PAYLOAD_CONFIG_PATH": "test/_community/config.ts",
|
||||
"DISABLE_SWC": "true" // SWC messes up debugging the bin scripts
|
||||
},
|
||||
"name": "Generate Types CLI",
|
||||
"outputCapture": "std",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "ts-node ./packages/payload/src/bin/index.ts migrate:status",
|
||||
"env": {
|
||||
|
||||
18
.vscode/settings.json
vendored
18
.vscode/settings.json
vendored
@@ -5,21 +5,21 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[json]": {
|
||||
@@ -35,5 +35,15 @@
|
||||
"eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
// Load .git-blame-ignore-revs file
|
||||
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"]
|
||||
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"],
|
||||
"[javascript][typescript][typescriptreact]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"files.insertFinalNewline": true,
|
||||
"jestrunner.jestCommand": "pnpm exec cross-env NODE_OPTIONS=\"--experimental-vm-modules --no-deprecation\" node 'node_modules/jest/bin/jest.js'",
|
||||
"jestrunner.debugOptions": {
|
||||
"runtimeArgs": ["--experimental-vm-modules", "--no-deprecation"]
|
||||
}
|
||||
}
|
||||
|
||||
350
CHANGELOG.md
350
CHANGELOG.md
@@ -1,3 +1,353 @@
|
||||
## [2.11.2](https://github.com/payloadcms/payload/compare/v2.11.1...v2.11.2) (2024-02-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** configurable custom schema to use ([#5047](https://github.com/payloadcms/payload/issues/5047)) ([e8f2ca4](https://github.com/payloadcms/payload/commit/e8f2ca484ee56cd7767d5111e46ebd24752ff8de))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add Context Provider in EditMany Component ([#5005](https://github.com/payloadcms/payload/issues/5005)) ([70e57fe](https://github.com/payloadcms/payload/commit/70e57fef184f7fcf56344ea755465f246f2253a5))
|
||||
* **db-mongodb:** unique sparse for not required fields ([#5114](https://github.com/payloadcms/payload/issues/5114)) ([815bdfa](https://github.com/payloadcms/payload/commit/815bdfac0b0afbff2a20e54d5aee64b90f6b3a77))
|
||||
* **db-postgres:** set _parentID for array nested localized fields ([#5117](https://github.com/payloadcms/payload/issues/5117)) ([ceca5c4](https://github.com/payloadcms/payload/commit/ceca5c4e97f53f1346797a31b6abfc0375e98215))
|
||||
* disabling API Key does not remove the key ([#5145](https://github.com/payloadcms/payload/issues/5145)) ([7a7f0ed](https://github.com/payloadcms/payload/commit/7a7f0ed7e8132253be607c111c160163b84bd770))
|
||||
* handle thrown errors in config-level afterError hook ([#5147](https://github.com/payloadcms/payload/issues/5147)) ([32ed95e](https://github.com/payloadcms/payload/commit/32ed95e1ee87409db234f1b7bd6d2e462fd9ed5d))
|
||||
* only replace the drawer content with full edit component if it exists ([#5144](https://github.com/payloadcms/payload/issues/5144)) ([0a07f60](https://github.com/payloadcms/payload/commit/0a07f607b9fb1217ad956cd05b2a84a4042a19ca))
|
||||
* transaction error from access endpoint ([#5156](https://github.com/payloadcms/payload/issues/5156)) ([ad42d54](https://github.com/payloadcms/payload/commit/ad42d541b342ed56463b81cee6d6307df6f06d7f))
|
||||
|
||||
## [2.11.1](https://github.com/payloadcms/payload/compare/v2.11.0...v2.11.1) (2024-02-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** adds idType to use uuid or serial id columns ([#3864](https://github.com/payloadcms/payload/issues/3864)) ([d6c2578](https://github.com/payloadcms/payload/commit/d6c25783cfa97983bf9db27ceb5ccd39a62c62f1))
|
||||
* **db-postgres:** reconnect after disconnection from database ([#5086](https://github.com/payloadcms/payload/issues/5086)) ([bf942fd](https://github.com/payloadcms/payload/commit/bf942fdfa6ea9c26cf05295cc9db646bf31fa622))
|
||||
* **plugin-search:** add req to beforeSync args for transactions ([#5068](https://github.com/payloadcms/payload/issues/5068)) ([98b87e2](https://github.com/payloadcms/payload/commit/98b87e22782c0a788f79326f22be05a6b176ad74))
|
||||
* **richtext-lexical:** add justify aligment to AlignFeature ([#4035](https://github.com/payloadcms/payload/issues/4035)) ([#4868](https://github.com/payloadcms/payload/issues/4868)) ([6d6823c](https://github.com/payloadcms/payload/commit/6d6823c3e5609a58eeeeb8d043945a762f9463df))
|
||||
* **richtext-lexical:** AddBlock handle for all nodes, even if they aren't empty paragraphs ([#5063](https://github.com/payloadcms/payload/issues/5063)) ([00fc034](https://github.com/payloadcms/payload/commit/00fc0343dabf184d5bab418d47c403b3ad11698f))
|
||||
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground ([#5066](https://github.com/payloadcms/payload/issues/5066)) ([0d18822](https://github.com/payloadcms/payload/commit/0d18822062275c1826c8e2c3da2571a2b3483310))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db-mongodb:** find versions pagination ([#5091](https://github.com/payloadcms/payload/issues/5091)) ([5d4022f](https://github.com/payloadcms/payload/commit/5d4022f1445e2809c01cb1dd599280f0a56cdc6e))
|
||||
* **db-postgres:** query using blockType ([#5044](https://github.com/payloadcms/payload/issues/5044)) ([35c2a08](https://github.com/payloadcms/payload/commit/35c2a085efa6d5ad59779960874bc9728a17e3a0))
|
||||
* filterOptions errors cause transaction to abort ([#5079](https://github.com/payloadcms/payload/issues/5079)) ([5f3d016](https://github.com/payloadcms/payload/commit/5f3d0169bee21e1c0963dbd7ede9fe5f1c46a5a5))
|
||||
* **plugin-form-builder:** hooks do not respect transactions ([#5069](https://github.com/payloadcms/payload/issues/5069)) ([82e9d31](https://github.com/payloadcms/payload/commit/82e9d31127c8df83c5bed92a5ffdab76d331900f))
|
||||
* remove collection findByID caching ([#5034](https://github.com/payloadcms/payload/issues/5034)) ([1ac943e](https://github.com/payloadcms/payload/commit/1ac943ed5e8416883b863147fdf3c23380955559))
|
||||
* **richtext-lexical:** do not remove adjacent paragraph node when inserting certain nodes in empty editor ([#5061](https://github.com/payloadcms/payload/issues/5061)) ([6323965](https://github.com/payloadcms/payload/commit/6323965c652ea68dffeb716957b124d165b9ce96))
|
||||
* **uploads:** account for serverURL when retrieving external file ([#5102](https://github.com/payloadcms/payload/issues/5102)) ([25cee8b](https://github.com/payloadcms/payload/commit/25cee8bb102bf80b3a4bfb4b4e46712722cc7f0d))
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES: @payloadcms/richtext-lexical
|
||||
|
||||
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground (#5066)
|
||||
|
||||
- You HAVE to make sure that any versions of the lexical packages (IF you have any installed) match the lexical version which richtext-lexical uses: v0.13.1. If you do not do this, you may be plagued by React useContext / "cannot find active editor state" errors
|
||||
- Updates to lexical's API, e.g. the removal of INTERNAL_isPointSelection, could be breaking depending on your code. Please consult the [lexical changelog](https://github.com/facebook/lexical/blob/main/CHANGELOG.md).
|
||||
|
||||
## [2.11.0](https://github.com/payloadcms/payload/compare/v2.10.1...v2.11.0) (2024-02-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* exposes collapsible provider with more functionality ([#5043](https://github.com/payloadcms/payload/issues/5043)) ([df39602](https://github.com/payloadcms/payload/commit/df39602758ae8dc3765bb48e51f7a657babfa559))
|
||||
|
||||
## [2.10.1](https://github.com/payloadcms/payload/compare/v2.10.0...v2.10.1) (2024-02-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clearable cells handle null values ([#5038](https://github.com/payloadcms/payload/issues/5038)) ([f6d7da7](https://github.com/payloadcms/payload/commit/f6d7da751039df25066b51bb91d6453e1a4efd82))
|
||||
* **db-mongodb:** handle null values with exists ([#5037](https://github.com/payloadcms/payload/issues/5037)) ([cdc4cb9](https://github.com/payloadcms/payload/commit/cdc4cb971b9180ba2ed09741f5af1a3c18292828))
|
||||
* **db-postgres:** handle nested docs with drafts ([#5012](https://github.com/payloadcms/payload/issues/5012)) ([da184d4](https://github.com/payloadcms/payload/commit/da184d40ece74bffb224002eb5df8f6987d65043))
|
||||
* ensures docs with the same id are shown in relationship field select ([#4859](https://github.com/payloadcms/payload/issues/4859)) ([e1813fb](https://github.com/payloadcms/payload/commit/e1813fb884e0dc84203fcbab87527a99a4d3a5d7))
|
||||
* query relationships by explicit id field ([#5022](https://github.com/payloadcms/payload/issues/5022)) ([a0a58e7](https://github.com/payloadcms/payload/commit/a0a58e7fd20dff54d210c968f4d5defd67441bdd))
|
||||
* **richtext-lexical:** make editor reactive to initialValue changes ([#5010](https://github.com/payloadcms/payload/issues/5010)) ([2315781](https://github.com/payloadcms/payload/commit/2315781f1891ddde4b4c5f2f0cfa1c17af85b7a9))
|
||||
|
||||
## [2.10.0](https://github.com/payloadcms/payload/compare/v2.9.0...v2.10.0) (2024-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add more options to addFieldStatePromise so that it can be used for field flattening ([#4799](https://github.com/payloadcms/payload/issues/4799)) ([8725d41](https://github.com/payloadcms/payload/commit/8725d411645bb0270376e235669f46be2227ecc0))
|
||||
* extend transactions to cover after and beforeOperation hooks ([#4960](https://github.com/payloadcms/payload/issues/4960)) ([1e8a6b7](https://github.com/payloadcms/payload/commit/1e8a6b7899f7b1e6451cc4d777602208478b483c))
|
||||
* previousValue and previousSiblingDoc args added to beforeChange field hooks ([#4958](https://github.com/payloadcms/payload/issues/4958)) ([5d934ba](https://github.com/payloadcms/payload/commit/5d934ba02d07d98f781ce983228858ee5ce5c226))
|
||||
* re-use existing logger instance passed to payload.init ([#3124](https://github.com/payloadcms/payload/issues/3124)) ([471d211](https://github.com/payloadcms/payload/commit/471d2113a790dc0d54b2f8ed84e6899310efd600))
|
||||
* **richtext-lexical:** Blocks: generate type definitions for blocks fields ([#4529](https://github.com/payloadcms/payload/issues/4529)) ([90d7ee3](https://github.com/payloadcms/payload/commit/90d7ee3e6535d51290fc734b284ff3811dbda1f8))
|
||||
* use deletion success message from server if provided ([#4966](https://github.com/payloadcms/payload/issues/4966)) ([e3c8105](https://github.com/payloadcms/payload/commit/e3c8105cc2ed6fdf8007d97cd7b5556fc71ed724))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db-postgres:** filtering relationships with drafts enabled ([#4998](https://github.com/payloadcms/payload/issues/4998)) ([c3a3942](https://github.com/payloadcms/payload/commit/c3a39429697e9d335e9be199e7caafb82eb26219))
|
||||
* **db-postgres:** handle schema changes with supabase ([#4968](https://github.com/payloadcms/payload/issues/4968)) ([5d3659d](https://github.com/payloadcms/payload/commit/5d3659d48ad8bbf5d96fbcd80434d2287cab97e0))
|
||||
* **db-postgres:** indexes not created for non unique field names ([#4967](https://github.com/payloadcms/payload/issues/4967)) ([64f705c](https://github.com/payloadcms/payload/commit/64f705c3c94148972f67e8175e718015760d6430))
|
||||
* **db-postgres:** indexes not creating for relationships, arrays, hasmany and blocks ([#4976](https://github.com/payloadcms/payload/issues/4976)) ([47106d5](https://github.com/payloadcms/payload/commit/47106d5a1af2ebd073fbbc6e474174c3d3835e5c))
|
||||
* **db-postgres:** localized field sort count ([#4997](https://github.com/payloadcms/payload/issues/4997)) ([f3876c2](https://github.com/payloadcms/payload/commit/f3876c2a39efe19a1864213306725aadcc14f130))
|
||||
* ensures docPermissions fallback to collection permissions on create ([#4969](https://github.com/payloadcms/payload/issues/4969)) ([afa2b94](https://github.com/payloadcms/payload/commit/afa2b942e0aad90c55744ae13e0ffe1cefa4585d))
|
||||
* **migrations:** safely create migration file when no name passed ([#4995](https://github.com/payloadcms/payload/issues/4995)) ([0740d50](https://github.com/payloadcms/payload/commit/0740d5095ee1aef13e4e37f6b174d529f0f2d993))
|
||||
* **plugin-seo:** tabbedUI with email field causes duplicate field ([#4944](https://github.com/payloadcms/payload/issues/4944)) ([db22cbd](https://github.com/payloadcms/payload/commit/db22cbdf21a39ed0604ab96c57ca4242eac82ce7))
|
||||
|
||||
## [2.9.0](https://github.com/payloadcms/payload/compare/v2.8.2...v2.9.0) (2024-01-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* forceAcceptWarning migration arg added to accept prompts ([#4874](https://github.com/payloadcms/payload/issues/4874)) ([eba53ba](https://github.com/payloadcms/payload/commit/eba53ba60afd7c5d37389377ed06a9b556058d49))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* afterLogin hook write conflicts ([#4904](https://github.com/payloadcms/payload/issues/4904)) ([3eb681e](https://github.com/payloadcms/payload/commit/3eb681e847e9c55eaaa69c22bea4f4e66c7eac36))
|
||||
* **db-postgres:** migrate down error ([#4861](https://github.com/payloadcms/payload/issues/4861)) ([dfba522](https://github.com/payloadcms/payload/commit/dfba5222f3abf3f236dc9212a28e1aec7d7214d5))
|
||||
* **db-postgres:** query unset relation ([#4862](https://github.com/payloadcms/payload/issues/4862)) ([8ce15c8](https://github.com/payloadcms/payload/commit/8ce15c8b07800397a50dcf790c263ed5b3cfad53))
|
||||
* migrate down missing filter for latest batch ([#4860](https://github.com/payloadcms/payload/issues/4860)) ([b99d24f](https://github.com/payloadcms/payload/commit/b99d24fcfa698c493ea01c41621201abe18fabe3))
|
||||
* **plugin-cloud-storage:** slow get file performance large collections ([#4927](https://github.com/payloadcms/payload/issues/4927)) ([f73d503](https://github.com/payloadcms/payload/commit/f73d503fecdfa5cefdc26ab9aad60b00563f881e))
|
||||
* remove No Options dropdown from hasMany fields ([#4899](https://github.com/payloadcms/payload/issues/4899)) ([e5a7907](https://github.com/payloadcms/payload/commit/e5a7907a72c1371447ac2f71fce213ed22246092))
|
||||
* upload input drawer does not show draft versions ([#4903](https://github.com/payloadcms/payload/issues/4903)) ([6930c4e](https://github.com/payloadcms/payload/commit/6930c4e9f2200853121391ad8f8df48ea66c40a4))
|
||||
|
||||
## [2.8.2](https://github.com/payloadcms/payload/compare/v2.8.1...v2.8.2) (2024-01-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** support drizzle logging config ([#4809](https://github.com/payloadcms/payload/issues/4809)) ([371353f](https://github.com/payloadcms/payload/commit/371353f1535fbab4ebd9f56fc14fd10a30eec289))
|
||||
* **plugin-form-builder:** add validation for form ID when creating a submission ([#4730](https://github.com/payloadcms/payload/pull/4730))
|
||||
* **plugin-seo:** add support for interfaceName and fieldOverrides ([#4695](https://github.com/payloadcms/payload/pull/4695))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db-mongodb:** mongodb versions creating duplicates ([#4825](https://github.com/payloadcms/payload/issues/4825)) ([a861311](https://github.com/payloadcms/payload/commit/a861311c5a98126700f98f9a2ab380782e754717))
|
||||
* **db-mongodb:** transactionOptions=false typeErrors ([82383a5](https://github.com/payloadcms/payload/commit/82383a5b5f52785115c0feb970da70e91971b7ca))
|
||||
* **db-postgres:** Remove duplicate keys from response ([#4747](https://github.com/payloadcms/payload/issues/4747)) ([eb9e771](https://github.com/payloadcms/payload/commit/eb9e771a9ca03636486d36654f215b73435574cb))
|
||||
* **db-postgres:** validateExistingBlockIsIdentical with arrays ([3b88adc](https://github.com/payloadcms/payload/commit/3b88adc7d0594af63ce190c40c9ee3905df67a31))
|
||||
* **db-postgres:** validateExistingBlockIsIdentical with other tables ([0647c87](https://github.com/payloadcms/payload/commit/0647c870f15dc1b122734b678c2abeb6f56377d4))
|
||||
* **plugin-seo:** fix missing spread operator in URL generator function ([#4723](https://github.com/payloadcms/payload/pull/4723))
|
||||
* removes max-width from field-types class & correctly sets it on uploads ([#4829](https://github.com/payloadcms/payload/issues/4829)) ([ee5390a](https://github.com/payloadcms/payload/commit/ee5390aaca37a4154cde8392b60f091ec3e5175c))
|
||||
|
||||
## [2.8.1](https://github.com/payloadcms/payload/compare/v2.8.0...v2.8.1) (2024-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* corrects config usage in build bin script ([#4796](https://github.com/payloadcms/payload/issues/4796)) ([775502b](https://github.com/payloadcms/payload/commit/775502b1616c1bd35a3044438e253a0e84219f99))
|
||||
|
||||
## [2.8.0](https://github.com/payloadcms/payload/compare/v2.7.0...v2.8.0) (2024-01-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow custom config properties in blocks ([#4766](https://github.com/payloadcms/payload/issues/4766)) ([d92af29](https://github.com/payloadcms/payload/commit/d92af295ebe253160ac4c8fb788a1fb143ab85ae))
|
||||
* **logger:** show local time ([#4663](https://github.com/payloadcms/payload/issues/4663)) ([493fde5](https://github.com/payloadcms/payload/commit/493fde5ccceb9a95d0b950a028a1d2f8888b4e64))
|
||||
* **plugin-cloud:** use resend smtp instead of custom transport ([#4746](https://github.com/payloadcms/payload/issues/4746)) ([5cfde54](https://github.com/payloadcms/payload/commit/5cfde542b19988985746e220829d429a84ba3976))
|
||||
* **plugin-seo:** add fr translations ([#4774](https://github.com/payloadcms/payload/issues/4774)) ([4319fe1](https://github.com/payloadcms/payload/commit/4319fe1c6e332d35124356ce5d5d0fb48fe199e7))
|
||||
* **plugin-seo:** remove support for payload <2.7.0 ([#4765](https://github.com/payloadcms/payload/issues/4765)) ([5e08368](https://github.com/payloadcms/payload/commit/5e083689d016fbff6c83419336e920f248932993))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow a custom ID field to be nested inside unnamed tabs and rows ([#4701](https://github.com/payloadcms/payload/issues/4701)) ([6d5ac1d](https://github.com/payloadcms/payload/commit/6d5ac1de1ef55c4d51b253b4cf959bb703316c49))
|
||||
* build payload without initializing ([#4028](https://github.com/payloadcms/payload/issues/4028)) ([1115387](https://github.com/payloadcms/payload/commit/11153877447af68389dde80fff2f9ee869468acb))
|
||||
* **db-mongodb:** limit=0 returns unpaginated ([63e5c43](https://github.com/payloadcms/payload/commit/63e5c43fe620458936e2ebc4f5468aff9cb23e02))
|
||||
* **db-postgres:** totalPages value when limit=0 ([5702b83](https://github.com/payloadcms/payload/commit/5702b83e829b5b1a3d95ce4a1c1967c3ec630373))
|
||||
* migration regression ([#4777](https://github.com/payloadcms/payload/issues/4777)) ([fa3b3dd](https://github.com/payloadcms/payload/commit/fa3b3dd62d0a060f7419fd21d69eafff9bf99a61))
|
||||
* **db-mongodb:** migration regression ([#4777](https://github.com/payloadcms/payload/issues/4777)) ([fa3b3dd](https://github.com/payloadcms/payload/commit/fa3b3dd62d0a060f7419fd21d69eafff9bf99a61))
|
||||
* **db-postgres:**migration regression ([#4777](https://github.com/payloadcms/payload/issues/4777)) ([fa3b3dd](https://github.com/payloadcms/payload/commit/fa3b3dd62d0a060f7419fd21d69eafff9bf99a61))
|
||||
* passes `draft=true` in fetch for relationships ([#4784](https://github.com/payloadcms/payload/issues/4784)) ([0a259d2](https://github.com/payloadcms/payload/commit/0a259d27b5ef0d632ca54cd0a9ab99629f94c2a0))
|
||||
* **plugin-form-builder:** replaces curly brackets with lexical editor ([#4753](https://github.com/payloadcms/payload/issues/4753)) ([8481846](https://github.com/payloadcms/payload/commit/84818469ea50d43276915d36bd92769422eadeb0))
|
||||
* prioritizes `value` key when filtering / querying for relationships ([#4727](https://github.com/payloadcms/payload/issues/4727)) ([d0f7677](https://github.com/payloadcms/payload/commit/d0f7677d5ff2e0109fc348260d87e2606fdbd293))
|
||||
* text hasMany validation ([#4789](https://github.com/payloadcms/payload/issues/4789)) ([e2e56a4](https://github.com/payloadcms/payload/commit/e2e56a4d58a9e1c31c05a0624f35642f58da162b))
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
#### @payloadcms/plugin-seo
|
||||
|
||||
* remove support for payload <2.7.0 ([#4765](https://github.com/payloadcms/payload/pull/4765))
|
||||
|
||||
## [2.7.0](https://github.com/payloadcms/payload/compare/v2.6.0...v2.7.0) (2024-01-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-mongodb:** improve transaction support by passing req to migrations ([682eca2](https://github.com/payloadcms/payload/commit/682eca21860a4e2b2ab0bfd85613818790247224))
|
||||
* **db-postgres:** improve transaction support by passing req to migrations ([555d027](https://github.com/payloadcms/payload/commit/555d02769a8731aeebbff9b67f9b0e1022904ade))
|
||||
* hasMany property for text fields ([#4605](https://github.com/payloadcms/payload/issues/4605)) ([f43cf18](https://github.com/payloadcms/payload/commit/f43cf185d45b3c75fa0d78acd91e6cb60d87f166))
|
||||
* improve transaction support by passing req to migrations ([1d14d9f](https://github.com/payloadcms/payload/commit/1d14d9f8b8ed077691175030182f094bb300ed17))
|
||||
* **plugin-seo:** add i18n ([#4665](https://github.com/payloadcms/payload/issues/4665)) ([3027a03](https://github.com/payloadcms/payload/commit/3027a03ad11ecd679278e44a013e4dea4aa42b8d))
|
||||
* provide document info to ActionsProvider ([#4696](https://github.com/payloadcms/payload/issues/4696)) ([6a8a6e4](https://github.com/payloadcms/payload/commit/6a8a6e4ef4913e0889e4d2eac82b28b9e4e8db22))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* adds objectID validation to isValidID if of type `text` ([#4689](https://github.com/payloadcms/payload/issues/4689)) ([d419275](https://github.com/payloadcms/payload/commit/d419275fb50f0922307f2d3b4c0fcf80ac5ec98b))
|
||||
* allow json field to be saved empty and reflect value changes ([#4687](https://github.com/payloadcms/payload/issues/4687)) ([0fb3a9c](https://github.com/payloadcms/payload/commit/0fb3a9ca89d1b63faea179bfa9b5b3d0a69c9398))
|
||||
* custom ids in versions ([#4680](https://github.com/payloadcms/payload/issues/4680)) ([5d15955](https://github.com/payloadcms/payload/commit/5d15955f839d3f0cc557d8a8d7cc3a9e52e2f6b1))
|
||||
* custom overrides of breadcrumb and parent fields ([7db58b4](https://github.com/payloadcms/payload/commit/7db58b482bba7e715c5be23cfe1a84295e95da29))
|
||||
* **db-mongodb:** migration error calling beginTransaction with transactionOptions false ([21b9453](https://github.com/payloadcms/payload/commit/21b9453cf4e6eebf145d89a0190942015658413d))
|
||||
* **db-mongodb:** querying plan for collections ignoring indexes ([#4655](https://github.com/payloadcms/payload/issues/4655)) ([63bc4ca](https://github.com/payloadcms/payload/commit/63bc4cabe1dea5f233aa1d9d4e64f3af93a8e081))
|
||||
* **db-postgres:** incorrect results querying json field using exists operator ([9d9ac0e](https://github.com/payloadcms/payload/commit/9d9ac0ec28c97281bfdc7d6fb78c52baea492380))
|
||||
* **db-postgres:** migrate down only runs latest batch size ([6acfae8](https://github.com/payloadcms/payload/commit/6acfae8ee7614746797e1fa91e1fd41c0240fdcd))
|
||||
* **db-postgres:** query on json properties ([ec4d2f9](https://github.com/payloadcms/payload/commit/ec4d2f97cbf1c89d837372059bf3bb77f3ea6594))
|
||||
* **db-postgres:** validation prevents group fields in blocks ([#4699](https://github.com/payloadcms/payload/issues/4699)) ([cab6bab](https://github.com/payloadcms/payload/commit/cab6babd608daeaabf9b63b1b446fded6804b60f))
|
||||
* non-boolean condition result causes infinite looping ([#4579](https://github.com/payloadcms/payload/issues/4579)) ([a3e7816](https://github.com/payloadcms/payload/commit/a3e78161b551e8286063a173645a1d3dee162ad1))
|
||||
* **plugin-form-builder:** slate serializer should replace curly braces in links ([#4703](https://github.com/payloadcms/payload/issues/4703)) ([28a3012](https://github.com/payloadcms/payload/commit/28a30120dd1aa3279fb2133aa0a0b1638d144be4))
|
||||
* **plugin-nested-docs:** breadcrumbsFieldSlug used in resaveSelfAfterCreate hook ([a5a91c0](https://github.com/payloadcms/payload/commit/a5a91c08a9ade1482c512d3fa4c4f519ad85cf74))
|
||||
* **plugin-nested-docs:** children wrongly publishing draft data ([#4692](https://github.com/payloadcms/payload/issues/4692)) ([5539942](https://github.com/payloadcms/payload/commit/55399424a13b1e0532d9eeefd09d442c107c3eda))
|
||||
* **plugin-nested-docs:** custom parent field slug ([635e7c2](https://github.com/payloadcms/payload/commit/635e7c26e8b3b5138cf5a9bcb29e8ddd4b1e69b6))
|
||||
* **plugin-nested-docs:** parent filterOptions errors when specifying breadcrumbsFieldSlug ([c4a4678](https://github.com/payloadcms/payload/commit/c4a4678afb097cf94c682595a78e416767a1fea8))
|
||||
* prevents row overflow ([#4704](https://github.com/payloadcms/payload/issues/4704)) ([9828772](https://github.com/payloadcms/payload/commit/98287728900cb88fa6a465899f030f81df28fc69))
|
||||
* relations with number based ids (postgres) show untitled ID: x ([1b91408](https://github.com/payloadcms/payload/commit/1b914083c8ee0c1b1d64fa7d4471ede0a24cfdb7))
|
||||
* sidebar fields not disabled by access permissions ([#4682](https://github.com/payloadcms/payload/issues/4682)) ([85e38b7](https://github.com/payloadcms/payload/commit/85e38b7cfd5c0772344c4a8fb5100f7c48eb508f))
|
||||
* unlock user condition always passes due to seconds conversion ([#4610](https://github.com/payloadcms/payload/issues/4610)) ([d543665](https://github.com/payloadcms/payload/commit/d543665995410256f77fe136173339aee6dcc7da))
|
||||
|
||||
## [2.6.0](https://github.com/payloadcms/payload/compare/v2.5.0...v2.6.0) (2024-01-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-mongodb:** add transactionOptions ([f2c8ac4](https://github.com/payloadcms/payload/commit/f2c8ac4a9aa9120339af6759170f5a708469698d))
|
||||
* extend locales to have fallbackLocales ([9fac2ef](https://github.com/payloadcms/payload/commit/9fac2ef24e2ade4cf55b0d6a0e7f67e0edf57539))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* "The punycode module is deprecated" warning by updating nodemailer ([00d8480](https://github.com/payloadcms/payload/commit/00d8480062d99dee56ef61a955f48a92efa6cbea))
|
||||
* adjusts json field joi schema to allow editorOptions ([bff4cf5](https://github.com/payloadcms/payload/commit/bff4cf518f748efb9179f112c606d11d25db3d99))
|
||||
* **db-postgres:** Wait for transaction to complete on commit ([#4582](https://github.com/payloadcms/payload/issues/4582)) ([a71d37b](https://github.com/payloadcms/payload/commit/a71d37b39806cd5956378a10246802d01d06c2dd))
|
||||
* detect language from request headers accept-language ([#4656](https://github.com/payloadcms/payload/issues/4656)) ([69a9944](https://github.com/payloadcms/payload/commit/69a99445c9f1638a962a9c08ffe0bdc22e538bf6))
|
||||
* graphql multiple locales ([98890ee](https://github.com/payloadcms/payload/commit/98890eee1f527c8f245b2353d7e1caca4d2a7d8c))
|
||||
* navigation locks when modal is closed with esc ([#4664](https://github.com/payloadcms/payload/issues/4664)) ([be3beab](https://github.com/payloadcms/payload/commit/be3beabb9bafa137aa89e84cf47246017e969be8))
|
||||
* req.locale and req.fallbackLocale get reassigned in local operations ([aa048d5](https://github.com/payloadcms/payload/commit/aa048d5409acd42b8f56367a16934085df9fbce2))
|
||||
* resets actions array when navigating out of view with actions ([#4585](https://github.com/payloadcms/payload/issues/4585)) ([5c55231](https://github.com/payloadcms/payload/commit/5c5523195ccfa94a9bf42441e2a378f87836e64d))
|
||||
* **richtext-lexical:** z-index issues ([#4570](https://github.com/payloadcms/payload/issues/4570)) ([8015e99](https://github.com/payloadcms/payload/commit/8015e999cd5834f532a200ef03fd392d04b3209f))
|
||||
* tab field error when using the same interface name ([#4657](https://github.com/payloadcms/payload/issues/4657)) ([f1fa374](https://github.com/payloadcms/payload/commit/f1fa374ed12b50fdf210f17ae1dda603f09a9726))
|
||||
|
||||
## [2.5.0](https://github.com/payloadcms/payload/compare/v2.4.0...v2.5.0) (2023-12-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Chinese Traditional translation ([#4372](https://github.com/payloadcms/payload/issues/4372)) ([50253f6](https://github.com/payloadcms/payload/commit/50253f617c22d0d185bbac7f9d4304cddbc01f06))
|
||||
* add context to auth and globals local API ([#4449](https://github.com/payloadcms/payload/issues/4449)) ([168d629](https://github.com/payloadcms/payload/commit/168d6296974042c3ff2a113f9f6c2bded7ba2b3e))
|
||||
* adds new `actions` property to admin customization ([#4468](https://github.com/payloadcms/payload/issues/4468)) ([9e8f14a](https://github.com/payloadcms/payload/commit/9e8f14a897e77f6933eedb2410956a468f4187c3))
|
||||
* async live preview urls ([#4339](https://github.com/payloadcms/payload/issues/4339)) ([5f17324](https://github.com/payloadcms/payload/commit/5f173241df6dc316d498767b1c81718e9c2b9a51))
|
||||
* pass path to FieldDescription ([#4364](https://github.com/payloadcms/payload/issues/4364)) ([3b8a27d](https://github.com/payloadcms/payload/commit/3b8a27d199b3969cbca6ca750450798cb70f21e8))
|
||||
* **plugin-form-builder:** Lexical support ([#4487](https://github.com/payloadcms/payload/issues/4487)) ([c6c5cab](https://github.com/payloadcms/payload/commit/c6c5cabfbb7eb954eea51170a6af7582b1f9b84b))
|
||||
* prevent querying relationship when filterOptions returns false ([#4392](https://github.com/payloadcms/payload/issues/4392)) ([c1bd338](https://github.com/payloadcms/payload/commit/c1bd338d0d5e899f3892f1d18e355c00b265447a))
|
||||
* **richtext-lexical:** improve floating select menu Dropdown classNames ([#4444](https://github.com/payloadcms/payload/issues/4444)) ([9331204](https://github.com/payloadcms/payload/commit/9331204295bfeaf7dd10bc075f42995b2cab2de4))
|
||||
* **richtext-lexical:** improve link URL validation ([#4442](https://github.com/payloadcms/payload/issues/4442)) ([9babf68](https://github.com/payloadcms/payload/commit/9babf6804ce04d5828167eb8e7717727fe1cd472))
|
||||
* **richtext-lexical:** lazy import React components to prevent client-only code from leaking into the server ([#4290](https://github.com/payloadcms/payload/issues/4290)) ([5de347f](https://github.com/payloadcms/payload/commit/5de347ffffca3bf38315d3d87d2ccc5c28cd2723))
|
||||
* **richtext-lexical:** Link & Relationship Feature: field-level configurable allowed relationships ([#4182](https://github.com/payloadcms/payload/issues/4182)) ([7af8f29](https://github.com/payloadcms/payload/commit/7af8f29b4a8dddf389356e4db142f8d434cdc964))
|
||||
* **richtext-lexical:** link node: change doc data format to be consistent with relationship field ([#4504](https://github.com/payloadcms/payload/issues/4504)) ([cc0ba89](https://github.com/payloadcms/payload/commit/cc0ba895188f40181c6ba3779f66d547d4ea66f9))
|
||||
* **richtext-lexical:** rename TreeviewFeature into TreeViewFeature ([#4520](https://github.com/payloadcms/payload/issues/4520)) ([c49fd66](https://github.com/payloadcms/payload/commit/c49fd6692231b68ca61b079103a0fd7aa4673be1))
|
||||
* **richtext-lexical:** Slate to Lexical converter: add blockquote conversion, convert custom link fields ([#4486](https://github.com/payloadcms/payload/issues/4486)) ([31f8f3c](https://github.com/payloadcms/payload/commit/31f8f3cac6bfd08f3adfa0a026a57c4b1b510045))
|
||||
* **richtext-lexical:** Upload html serializer: Output picture element if the image has multiple sizes, improve absolute URL creation ([e558894](https://github.com/payloadcms/payload/commit/e55889480fceb8995646621923159d92de6e89c9))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* adds bg color for year/month select options in datepicker ([#4508](https://github.com/payloadcms/payload/issues/4508)) ([07371b9](https://github.com/payloadcms/payload/commit/07371b9cad111999f2df4e1f709d6b95cd511c15))
|
||||
* correctly fetches externally stored files when passing uploadEdits ([#4505](https://github.com/payloadcms/payload/issues/4505)) ([228d45c](https://github.com/payloadcms/payload/commit/228d45cf52e592cea6377cd93648fba75d73c88d))
|
||||
* cursor jumping around inside json field ([#4453](https://github.com/payloadcms/payload/issues/4453)) ([6300037](https://github.com/payloadcms/payload/commit/63000373e66fb39443f882689e0ecf5c11ed8ad0))
|
||||
* **db-mongodb:** documentDB unique constraint throws incorrect error ([#4513](https://github.com/payloadcms/payload/issues/4513)) ([05e8914](https://github.com/payloadcms/payload/commit/05e8914db70fa64bfb2d15ecfb58e9c229d71108))
|
||||
* **db-postgres:** findOne correctly querying with where queries ([#4550](https://github.com/payloadcms/payload/issues/4550)) ([8bc31cd](https://github.com/payloadcms/payload/commit/8bc31cd5923517ab39ae1427aa0d0fb19d876dab))
|
||||
* **db-postgres:** querying nested blocks fields ([#4404](https://github.com/payloadcms/payload/issues/4404)) ([6e9ae65](https://github.com/payloadcms/payload/commit/6e9ae65374124ee000cc2988ef77247c94b0dd18))
|
||||
* **db-postgres:** sorting on a not-configured field throws error ([#4382](https://github.com/payloadcms/payload/issues/4382)) ([dbaecda](https://github.com/payloadcms/payload/commit/dbaecda0e92fcb0fa67b4c5ac085e025f02de53a))
|
||||
* defaultValues computed on new globals ([#4380](https://github.com/payloadcms/payload/issues/4380)) ([b6cffce](https://github.com/payloadcms/payload/commit/b6cffcea07b9fa21698b00b8bbed6f27197ded41))
|
||||
* disallow duplicate fieldNames to be used on the same level in the config ([#4381](https://github.com/payloadcms/payload/issues/4381)) ([a1d66b8](https://github.com/payloadcms/payload/commit/a1d66b83e0dbea21e8da549b73cd25c537a57938))
|
||||
* ensure ui fields do not make it into gql schemas ([#4457](https://github.com/payloadcms/payload/issues/4457)) ([3a20ddc](https://github.com/payloadcms/payload/commit/3a20ddc5f85162a316006f22ba66ee1c7aab99e3))
|
||||
* format fields within tab for list controls ([#4516](https://github.com/payloadcms/payload/issues/4516)) ([2650c70](https://github.com/payloadcms/payload/commit/2650c70960a7374307a8862c3940c97d337d1d30))
|
||||
* formats locales with multiple labels for versions locale selector ([#4495](https://github.com/payloadcms/payload/issues/4495)) ([8257661](https://github.com/payloadcms/payload/commit/8257661c47b5b968a57fb2228d7045d876a3f484))
|
||||
* graphql schema generation for fields without queryable subfields ([#4463](https://github.com/payloadcms/payload/issues/4463)) ([13e3e06](https://github.com/payloadcms/payload/commit/13e3e0671353ca34e603fece57a12199f2082ca0))
|
||||
* handles null upload field values ([#4397](https://github.com/payloadcms/payload/issues/4397)) ([cf9a370](https://github.com/payloadcms/payload/commit/cf9a3704df21ce8b32feb0680793cba804cd66f7))
|
||||
* **live-preview:** populates rte uploads and relationships ([#4379](https://github.com/payloadcms/payload/issues/4379)) ([4090aeb](https://github.com/payloadcms/payload/commit/4090aebb0e94e776258f0c1c761044a4744a1857))
|
||||
* **live-preview:** sends raw js objects through window.postMessage instead of json ([#4354](https://github.com/payloadcms/payload/issues/4354)) ([03a3872](https://github.com/payloadcms/payload/commit/03a387233d1b8876a2fcaa5f3b3fd5ed512c0bc4))
|
||||
* make admin navigation transition smoother ([#4217](https://github.com/payloadcms/payload/issues/4217)) ([eb6572e](https://github.com/payloadcms/payload/commit/eb6572e9e56e680cad331c1bc5da47e91306deb9))
|
||||
* omit field default value if read access returns false ([#4518](https://github.com/payloadcms/payload/issues/4518)) ([3e9ef84](https://github.com/payloadcms/payload/commit/3e9ef849cd8e69e1e8d7f2f653f0647e93c8ab39))
|
||||
* pin ts-node versions which are causing swc errors ([#4447](https://github.com/payloadcms/payload/issues/4447)) ([b9c0248](https://github.com/payloadcms/payload/commit/b9c024882350d14edd57f0f662a2269ed37975e3))
|
||||
* properly spreads collection fields into non-tabbed configs [#50](https://github.com/payloadcms/payload/issues/50) ([#51](https://github.com/payloadcms/payload/issues/51)) ([7e88159](https://github.com/payloadcms/payload/commit/7e88159e99e2afdc10addc02cf299c11fe188be7))
|
||||
* **plugin-form-builder:** removes use of slate in rich-text serializer ([#4451](https://github.com/payloadcms/payload/issues/4451)) ([3df52a8](https://github.com/payloadcms/payload/commit/3df52a88568622f8fafeabad47c7501229e4ea5f))
|
||||
* **plugin-nested-docs:** properly exports field utilities ([#4462](https://github.com/payloadcms/payload/issues/4462)) ([1cc87bd](https://github.com/payloadcms/payload/commit/1cc87bd8ea575dfa2e1f5ce5b38414bbba95b2cb))
|
||||
* **richtext-*:** loosen RichTextAdapter types due to re-occuring ts strict mode errors ([#4416](https://github.com/payloadcms/payload/issues/4416)) ([48f1299](https://github.com/payloadcms/payload/commit/48f1299fcba3e3811c6a7f31499f238537f9a5e3))
|
||||
* **richtext-lexical:** Blocks field: should not prompt for unsaved changes due to value comparison between null and non-existent props ([#4450](https://github.com/payloadcms/payload/issues/4450)) ([548e78c](https://github.com/payloadcms/payload/commit/548e78c598cb6d029e7cc40f80d9855754f043bc))
|
||||
* **richtext-lexical:** do not add unnecessary paragraph before upload, relationship and blocks nodes ([#4441](https://github.com/payloadcms/payload/issues/4441)) ([5c2739e](https://github.com/payloadcms/payload/commit/5c2739ebd144620cfd4ff02531f5812dd62ac61d))
|
||||
* **richtext-lexical:** lexicalHTML field not working when used inside of Blocks field ([128f9c4](https://github.com/payloadcms/payload/commit/128f9c4e7e6e20dd1ee221f49428a5bce5179c5f))
|
||||
* **richtext-lexical:** lexicalHTML field now works when used inside of row fields ([#4440](https://github.com/payloadcms/payload/issues/4440)) ([0421173](https://github.com/payloadcms/payload/commit/0421173f9e2d6db1b6a94b25884ea807921f2d09))
|
||||
* **richtext-lexical:** not all types of URLs are validated correctly ([ac7f980](https://github.com/payloadcms/payload/commit/ac7f9809bc2b9fb6a52b48c10f7d51414801e4de))
|
||||
* searching by id sends undefined in where query param ([#4464](https://github.com/payloadcms/payload/issues/4464)) ([46e8c01](https://github.com/payloadcms/payload/commit/46e8c01fbed68856be68804f2bd9744c4c6f5a95))
|
||||
* simplifies query validation and fixes nested relationship fields ([#4391](https://github.com/payloadcms/payload/issues/4391)) ([4b5453e](https://github.com/payloadcms/payload/commit/4b5453e8e5484f7afcadbf5bccf8369b552969c6))
|
||||
* updates return value of empty arrays in getDataByPath ([#4553](https://github.com/payloadcms/payload/issues/4553)) ([f3748a1](https://github.com/payloadcms/payload/commit/f3748a1534a13e6d844aadd9f0e3e6acbe483d03))
|
||||
* upload editing error with plugin-cloud ([#4170](https://github.com/payloadcms/payload/issues/4170)) ([fcbe574](https://github.com/payloadcms/payload/commit/fcbe5744d945dc43642cdaa2007ddc252ecafafa))
|
||||
* upload related issues, cropping, fetching local file, external preview image ([#4461](https://github.com/payloadcms/payload/issues/4461)) ([45c472d](https://github.com/payloadcms/payload/commit/45c472d6b35c41e597038089ad1755cdb88193b6))
|
||||
* uploads files after validation ([#4218](https://github.com/payloadcms/payload/issues/4218)) ([65adfd2](https://github.com/payloadcms/payload/commit/65adfd21ed538b79628dc4f8ce9e1a5a1bba6aed))
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
#### @payloadcms/richtext-lexical
|
||||
|
||||
* **richtext-lexical:** rename TreeviewFeature into TreeViewFeature ([#4520](https://github.com/payloadcms/payload/issues/4520)) ([c49fd66](https://github.com/payloadcms/payload/commit/c49fd6692231b68ca61b079103a0fd7aa4673be1))
|
||||
|
||||
If you import TreeviewFeature, you have to rename the import to use TreeViewFeature (capitalized "V")
|
||||
|
||||
* **richtext-lexical:** link node: change doc data format to be consistent with relationship field ([#4504](https://github.com/payloadcms/payload/issues/4504)) ([cc0ba89](https://github.com/payloadcms/payload/commit/cc0ba895188f40181c6ba3779f66d547d4ea66f9))
|
||||
|
||||
An unpopulated, internal link node no longer saves the doc id under fields.doc.value.id. Now, it saves it under fields.doc.value.
|
||||
Migration inside of payload is automatic. If you are reading from the link node inside of your frontend though, you will have to adjust it.
|
||||
|
||||
* **richtext-lexical:** improve floating select menu Dropdown classNames ([#4444](https://github.com/payloadcms/payload/issues/4444)) ([9331204](https://github.com/payloadcms/payload/commit/9331204295bfeaf7dd10bc075f42995b2cab2de4))
|
||||
|
||||
Dropdown component has a new mandatory sectionKey prop
|
||||
|
||||
* **richtext-lexical:** lazy import React components to prevent client-only code from leaking into the server ([#4290](https://github.com/payloadcms/payload/issues/4290)) ([5de347f](https://github.com/payloadcms/payload/commit/5de347ffffca3bf38315d3d87d2ccc5c28cd2723))
|
||||
|
||||
1. Most important: If you are updating `@payloadcms/richtext-lexical` to v0.4.0 or higher, you will HAVE to update payload to the latest version as well. If you don't update it, payload likely won't start up due to validation errors. It's generally good practice to upgrade packages prefixed with @payloadcms/ together with payload and keep the versions in sync.
|
||||
|
||||
2. `@payloadcms/richtext-slate` is not affected by this.
|
||||
|
||||
3. Every single property in the `Feature` interface which accepts a React component now no longer accepts a React component, but a function which imports a React component instead. This is done to ensure no unnecessary client-only code is leaked to the server when importing Features on a server.
|
||||
Here's an example migration:
|
||||
|
||||
Old:
|
||||
|
||||
```ts
|
||||
import { BlockIcon } from '../../lexical/ui/icons/Block'
|
||||
...
|
||||
Icon: BlockIcon,
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```ts
|
||||
// import { BlockIcon } from '../../lexical/ui/icons/Block' // <= Remove this import
|
||||
...
|
||||
Icon: () =>
|
||||
// @ts-expect-error
|
||||
import('../../lexical/ui/icons/Block').then((module) => module.BlockIcon),
|
||||
```
|
||||
|
||||
Or alternatively, if you're using default exports instead of named exports:
|
||||
|
||||
```ts
|
||||
// import BlockIcon from '../../lexical/ui/icons/Block' // <= Remove this import
|
||||
...
|
||||
Icon: () =>
|
||||
// @ts-expect-error
|
||||
import('../../lexical/ui/icons/Block'),
|
||||
```
|
||||
|
||||
4. The types for `SanitizedEditorConfig` and `EditorConfig` have changed. Their respective `lexical` property no longer expects the `LexicalEditorConfig`. It now expects a function returning the `LexicalEditorConfig`. You will have to adjust this if you adjusted that property anywhere, e.g. when initializing the lexical field editor property, or when initializing a new headless editor.
|
||||
|
||||
5. The following exports are now exported from the `@payloadcms/richtext-lexical/components` subpath exports instead of `@payloadcms/richtext-lexical`:
|
||||
|
||||
- `ToolbarButton`
|
||||
- `ToolbarDropdown`
|
||||
- `RichTextCell`
|
||||
- `RichTextField`
|
||||
- `defaultEditorLexicalConfig`
|
||||
|
||||
You will have to adjust your imports, only if you import any of those properties in your project.
|
||||
|
||||
## @payloadcms/richtext-*
|
||||
|
||||
### [@payloadcms/richtext-lexical 0.4.1](https://github.com/payloadcms/payload/compare/richtext-lexical/0.4.0...richtext-lexical/0.4.1) (2023-12-07)
|
||||
|
||||
22
app/(payload)/admin/[[...segments]]/not-found.tsx
Normal file
22
app/(payload)/admin/[[...segments]]/not-found.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||
|
||||
export default NotFound
|
||||
22
app/(payload)/admin/[[...segments]]/page.tsx
Normal file
22
app/(payload)/admin/[[...segments]]/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||
|
||||
export default Page
|
||||
10
app/(payload)/api/[...slug]/route.ts
Normal file
10
app/(payload)/api/[...slug]/route.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = REST_GET(config)
|
||||
export const POST = REST_POST(config)
|
||||
export const DELETE = REST_DELETE(config)
|
||||
export const PATCH = REST_PATCH(config)
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
6
app/(payload)/api/graphql-playground/route.ts
Normal file
6
app/(payload)/api/graphql-playground/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
6
app/(payload)/api/graphql/route.ts
Normal file
6
app/(payload)/api/graphql/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
16
app/(payload)/layout.tsx
Normal file
16
app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
// import '@payloadcms/ui/styles.css' // Uncomment this line if `@payloadcms/ui/client` in `tsconfig.json` points to `/ui/dist` instead of `/ui/src`
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
|
||||
export default Layout
|
||||
5
app/my-route/route.ts
Normal file
5
app/my-route/route.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const GET = () => {
|
||||
return Response.json({
|
||||
hello: 'elliot',
|
||||
})
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
module.exports = {
|
||||
// gitRawCommitsOpts: {
|
||||
// from: 'v2.0.9',
|
||||
// path: 'packages/payload',
|
||||
// },
|
||||
// infile: 'CHANGELOG.md',
|
||||
options: {
|
||||
preset: {
|
||||
name: 'conventionalcommits',
|
||||
types: [
|
||||
{ section: 'Features', type: 'feat' },
|
||||
{ section: 'Features', type: 'feature' },
|
||||
{ section: 'Bug Fixes', type: 'fix' },
|
||||
{ section: 'Documentation', type: 'docs' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// outfile: 'NEW.md',
|
||||
writerOpts: {
|
||||
commitGroupsSort: (a, b) => {
|
||||
const groupOrder = ['Features', 'Bug Fixes', 'Documentation']
|
||||
return groupOrder.indexOf(a.title) - groupOrder.indexOf(b.title)
|
||||
},
|
||||
|
||||
// Scoped commits at the end, alphabetical sort
|
||||
commitsSort: (a, b) => {
|
||||
if (a.scope || b.scope) {
|
||||
if (!a.scope) return -1
|
||||
if (!b.scope) return 1
|
||||
return a.scope === b.scope
|
||||
? a.subject.localeCompare(b.subject)
|
||||
: a.scope.localeCompare(b.scope)
|
||||
}
|
||||
|
||||
// Alphabetical sort
|
||||
return a.subject.localeCompare(b.subject)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -3,7 +3,7 @@ title: Collection Access Control
|
||||
label: Collections
|
||||
order: 20
|
||||
desc: With Collection-level Access Control you can define which users can create, read, update or delete Collections.
|
||||
keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
You can define Collection-level Access Control within each Collection's `access` property. All Access Control functions accept one `args` argument.
|
||||
@@ -51,10 +51,10 @@ Returns a boolean which allows/denies access to the `create` request.
|
||||
|
||||
**Available argument properties:**
|
||||
|
||||
| Option | Description |
|
||||
| ---------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`data`** | The data passed to create the document with. |
|
||||
| Option | Description |
|
||||
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`data`** | The data passed to create the document with. |
|
||||
|
||||
**Example:**
|
||||
|
||||
@@ -80,7 +80,7 @@ Read access functions can return a boolean result or optionally return a [query
|
||||
|
||||
| Option | Description |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`id`** | `id` of document requested, if within `findByID` |
|
||||
|
||||
**Example:**
|
||||
@@ -111,7 +111,7 @@ Update access functions can return a boolean result or optionally return a [quer
|
||||
|
||||
| Option | Description |
|
||||
| ---------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`id`** | `id` of document requested to update |
|
||||
| **`data`** | The data passed to update the document with |
|
||||
|
||||
@@ -138,7 +138,7 @@ Similarly to the Update function, returns a boolean or a [query constraint](/doc
|
||||
|
||||
| Option | Description |
|
||||
| --------- | --------------------------------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object with additional `user` property, which is the currently logged in user |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object with additional `user` property, which is the currently logged in user |
|
||||
| **`id`** | `id` of document requested to delete |
|
||||
|
||||
**Example:**
|
||||
@@ -173,7 +173,7 @@ If the Collection is [used to access the Payload Admin panel](/docs/admin/overvi
|
||||
|
||||
| Option | Description |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
|
||||
### Unlock
|
||||
|
||||
@@ -183,4 +183,4 @@ Determines which users can [unlock](/docs/authentication/operations#unlock) othe
|
||||
|
||||
| Option | Description |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Field-level Access Control
|
||||
label: Fields
|
||||
order: 30
|
||||
desc: Field-level Access Control is specified within a field's config, and allows you to define which users can create, read or update Fields.
|
||||
keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Field Access Control is specified with functions inside a field's config. All field-level Controls return a boolean value to allow or deny access for the specified operation. No field-level Access Controls support returning query constraints. All Access Control functions accept one `args` argument.
|
||||
@@ -47,7 +47,7 @@ Returns a boolean which allows or denies the ability to set a field's value when
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`data`** | The full data passed to create the document. |
|
||||
| **`siblingData`** | Immediately adjacent field data passed to create the document. |
|
||||
|
||||
@@ -59,7 +59,7 @@ Returns a boolean which allows or denies the ability to read a field's value. If
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`id`** | `id` of the document being read |
|
||||
| **`doc`** | The full document data. |
|
||||
| **`siblingData`** | Immediately adjacent field data of the document being read. |
|
||||
@@ -74,7 +74,7 @@ If `false` is returned and you attempt to update the field's value, the operatio
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`id`** | `id` of the document being updated |
|
||||
| **`data`** | The full data passed to update the document. |
|
||||
| **`siblingData`** | Immediately adjacent field data passed to update the document with. |
|
||||
|
||||
@@ -3,13 +3,11 @@ title: Globals Access Control
|
||||
label: Globals
|
||||
order: 40
|
||||
desc: Global-level Access Control is specified within each Global's `access` property and allows you to define which users can read or update Globals.
|
||||
keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
You can define Global-level Access Control within each Global's `access` property. All Access Control functions accept one `args` argument.
|
||||
|
||||
\*\*Available argument properties:
|
||||
|
||||
## Available Controls
|
||||
|
||||
| Function | Allows/Denies Access |
|
||||
@@ -47,7 +45,7 @@ Returns a boolean result or optionally a [query constraint](/docs/queries/overvi
|
||||
|
||||
| Option | Description |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
|
||||
### Update
|
||||
|
||||
@@ -57,5 +55,5 @@ Returns a boolean result or optionally a [query constraint](/docs/queries/overvi
|
||||
|
||||
| Option | Description |
|
||||
| ---------- | -------------------------------------------------------------------------- |
|
||||
| **`req`** | The Express `request` object containing the currently authenticated `user` |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
|
||||
| **`data`** | The data passed to update the global with. |
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Access Control
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Payload makes it simple to define and manage access control. By declaring roles, you can set permissions and restrict what your users can interact with.
|
||||
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Access control within Payload is extremely powerful while remaining easy and intuitive to manage. Declaring who should have access to what documents is no more complex than writing a simple JavaScript function that either returns a `boolean` or a [`query`](/docs/queries/overview) constraint to restrict which documents users can interact with.
|
||||
@@ -19,9 +19,9 @@ Access control within Payload is extremely powerful while remaining easy and int
|
||||
- Restricting a `User` to only be able to see their own `Order`(s), but no others
|
||||
- Allowing `User`s that belong to a certain `Organization` to access only that `Organization`'s `Resource`s
|
||||
|
||||
### Default Settings
|
||||
## Default Settings
|
||||
|
||||
**By default, all Collections and Globals require that a user is logged in to be able to interact in any way.** The default Access Control function evaluates the `user` from the Express `req` and returns `true` if a user is logged in, and `false` if not.
|
||||
**By default, all Collections and Globals require that a user is logged in to be able to interact in any way.** The default Access Control function evaluates the `user` from the `req` and returns `true` if a user is logged in, and `false` if not.
|
||||
|
||||
**Default Access function:**
|
||||
|
||||
@@ -37,13 +37,15 @@ const defaultPayloadAccess = ({ req: { user } }) => {
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
In the Local API, all Access Control functions are skipped by default, allowing your server to do
|
||||
whatever it needs. But, you can opt back in by setting the option <strong>
|
||||
whatever it needs. But, you can opt back in by setting the option
|
||||
<strong>
|
||||
overrideAccess
|
||||
</strong>{' '}
|
||||
</strong>
|
||||
{' '}
|
||||
to <strong>false</strong>.
|
||||
</Banner>
|
||||
|
||||
### Access Control Types
|
||||
## Access Control Types
|
||||
|
||||
You can manage access within Payload on three different levels:
|
||||
|
||||
@@ -51,7 +53,7 @@ You can manage access within Payload on three different levels:
|
||||
- [Fields](/docs/access-control/fields)
|
||||
- [Globals](/docs/access-control/globals)
|
||||
|
||||
### When Access Control is Executed
|
||||
## When Access Control is Executed
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Note:</strong>
|
||||
@@ -60,17 +62,17 @@ You can manage access within Payload on three different levels:
|
||||
your access control is executed.
|
||||
</Banner>
|
||||
|
||||
#### As you execute operations
|
||||
### As you execute operations
|
||||
|
||||
When you perform Payload operations like `create`, `read`, `update`, and `delete`, your access control functions will be executed before any changes or operations are completed.
|
||||
|
||||
#### Within the Admin UI
|
||||
### Within the Admin UI
|
||||
|
||||
The Payload Admin UI responds dynamically to the access control that you define. For example, if you restrict editing a `ExampleCollection` to only users that feature a `role` of `admin`, the Payload Admin UI will **hide** the `ExampleCollection` from the Admin UI entirely. This is super powerful and allows you to control who can do what with your Admin UI.
|
||||
|
||||
To accomplish this, Payload ships with an `Access` operation, which is executed when a user logs into the Admin UI. Payload will execute each one of your access control functions, across all collections, globals, and fields, at the top level and return a response that contains a reflection of what the currently authenticated user can do with your application.
|
||||
|
||||
### Argument Availability
|
||||
## Argument Availability
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important:</strong>
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
title: Bundlers
|
||||
label: Bundlers
|
||||
order: 60
|
||||
desc: Bundlers are used to bundle the code that serves Payload's Admin Panel.
|
||||
---
|
||||
|
||||
Payload has two official bundlers, the [Webpack Bundler](/docs/admin/webpack) and the [Vite Bundler](/docs/admin/vite). You must install a bundler to use the admin panel.
|
||||
|
||||
##### Install a bundler
|
||||
|
||||
Webpack (recommended):
|
||||
|
||||
```text
|
||||
yarn add @payloadcms/bundler-webpack
|
||||
```
|
||||
|
||||
Vite (beta):
|
||||
|
||||
```text
|
||||
yarn add @payloadcms/bundler-vite
|
||||
```
|
||||
|
||||
##### Configure the bundler
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
// import { viteBundler } from '@payloadcms/bundler-vite'
|
||||
|
||||
export default buildConfig({
|
||||
// highlight-start
|
||||
admin: {
|
||||
bundler: webpackBundler() // or viteBundler()
|
||||
},
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
### What are bundlers?
|
||||
|
||||
At their core, a bundler's main goal is to take a bunch of files and turn them into a few optimized files that you ship to the browser. The admin UI has a root `index.html` entry point, and from there the bundler traverses the dependency tree, bundling all of the files that are required from that point on.
|
||||
|
||||
Since the bundled file is sent to the browser, it can't include any server-only code. You will need to remove any server-only code from your admin UI before bundling it. You can learn more about [excluding server code](/docs/admin/excluding-server-code) section.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Using environment variables in the admin UI</strong>
|
||||
<br />
|
||||
Bundles should not contain sensitive information. By default, Payload
|
||||
excludes env variables from the bundle. If you need to use env variables in your payload config,
|
||||
you need to prefix them with `PAYLOAD_PUBLIC_` to make them available to the client-side code.
|
||||
</Banner>
|
||||
@@ -3,39 +3,43 @@ title: Swap in your own React components
|
||||
label: Custom Components
|
||||
order: 20
|
||||
desc: Fully customize your Admin Panel by swapping in your own React components. Add fields, remove views, update routes and change functions to sculpt your perfect Dashboard.
|
||||
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
While designing the Payload Admin panel, we determined it should be as minimal and straightforward as possible to allow easy customization and control. There are many times where you may want to completely control how a whole view or a field works. You might even want to add in new views entirely. In order for Payload to support this level of customization without introducing versioning / future-proofing issues, Payload provides for a pattern to supply your own React components via your Payload config.
|
||||
The [Payload Admin](./overview) panel is designed to be as minimal and straightforward as possible to allow easy customization and control. In order for Payload to support this level of customization without introducing versioning or future-proofing issues, Payload provides a pattern for you to supply your own React components via your Payload config.
|
||||
|
||||
To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
|
||||
<Banner type="warning">
|
||||
All Custom Components in the Admin Panel are [React Server Components](https://react.dev/reference/rsc/server-components). This means they are rendered on the server
|
||||
</Banner>
|
||||
|
||||
To swap in your own React component, first, consult the list of available components below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
Custom components will automatically be provided with all props that the default component normally
|
||||
accepts.
|
||||
Custom components will automatically be provided with all props that the default component
|
||||
normally accepts.
|
||||
</Banner>
|
||||
|
||||
### Base Component Overrides
|
||||
## Base Component Overrides
|
||||
|
||||
You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
|
||||
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
|
||||
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
|
||||
| **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
|
||||
| **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/main/test/admin/components/AfterDashboard/index.tsx) |
|
||||
| **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
|
||||
| **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
|
||||
| **`logout.Button`** | A custom React component. |
|
||||
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
|
||||
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
|
||||
| **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
|
||||
| **`actions`** | Array of custom components to be rendered in the Payload Admin UI header, providing additional interactivity and functionality. |
|
||||
| **`views`** | Override or create new views within the Payload Admin UI. [More](#views) |
|
||||
| Path | Description |
|
||||
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
|
||||
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
|
||||
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
|
||||
| **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
|
||||
| **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/main/test/admin/components/AfterDashboard/index.tsx) |
|
||||
| **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
|
||||
| **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
|
||||
| **`logout.Button`** | A custom React component. |
|
||||
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
|
||||
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
|
||||
| **`providers`** | Define your own provider components that will wrap the [Admin Panel](./overview). [More](#custom-providers) |
|
||||
| **`actions`** | Array of custom components to be rendered in the [Admin Panel](./overview) header, providing additional interactivity and functionality. |
|
||||
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
|
||||
|
||||
Here is a full example showing how to swap some of these components for your own.
|
||||
|
||||
@@ -73,76 +77,7 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
#### Views
|
||||
|
||||
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
|
||||
| **`Dashboard`** | The main landing page of the Admin panel. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Account: MyCustomAccountView,
|
||||
Dashboard: MyCustomDashboardView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For more granular control, pass a configuration object instead. Each view corresponds to its own `<Route />` component in [React Router v5](https://v5.reactrouter.com). Payload exposes all of the properties of React Router:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
|
||||
| **`path`** \* | React Router `path`. [See the React Router docs](https://v5.reactrouter.com/web/api/Route/path-string-string) for more info. |
|
||||
| **`exact`** | React Router `exact` property. [More](https://v5.reactrouter.com/web/api/Route/exact-bool) |
|
||||
| **`strict`** | React Router `strict` property. [More](https://v5.reactrouter.com/web/api/Route/strict-bool) |
|
||||
| **`sensitive`** | React Router `sensitive` property. [More](https://v5.reactrouter.com/web/api/Route/sensitive-bool) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
#### Adding new views
|
||||
|
||||
To add a _new_ view to the Admin Panel, simply add another key to the `views` object with at least a `path` and `Component` property. For example:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
MyCustomView: {
|
||||
Component: MyCustomView,
|
||||
path: '/my-custom-view',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
Routes are cascading. This means that unless explicitly given the `exact` property, they will match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all routes in your application. Alternatively, you could define your nested route _before_ your parent route.
|
||||
</Banner>
|
||||
|
||||
_For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
|
||||
|
||||
For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component).
|
||||
|
||||
### Collections
|
||||
## Collections
|
||||
|
||||
You can override components on a collection-by-collection basis via the `admin.components` property.
|
||||
|
||||
@@ -156,25 +91,33 @@ You can override components on a collection-by-collection basis via the `admin.c
|
||||
| **`edit.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
|
||||
| **`edit.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
|
||||
| **`edit.PreviewButton`** | Replace the default `Preview` button with a custom component. |
|
||||
| **`views`** | Override or create new views within the Payload Admin UI. [More](#collection-views) |
|
||||
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
|
||||
|
||||
Here is a full example showing how to swap some of these components for your own:
|
||||
|
||||
`Collection.ts`
|
||||
`CustomSaveButton.tsx`
|
||||
|
||||
```tsx
|
||||
import * as React from 'react'
|
||||
import { CustomSaveButtonProps } from 'payload/types'
|
||||
|
||||
import {
|
||||
CustomSaveButtonProps,
|
||||
CustomSaveDraftButtonProps,
|
||||
CustomPublishButtonProps,
|
||||
CustomPreviewButtonProps,
|
||||
} from 'payload/types'
|
||||
|
||||
export const CustomSaveButton: CustomSaveButtonProps = ({ DefaultButton, label, save }) => {
|
||||
return <DefaultButton label={label} save={save} />
|
||||
const CustomSaveButton: CustomSaveButtonProps = ({
|
||||
DefaultButton,
|
||||
label,
|
||||
save
|
||||
}) => {
|
||||
return (
|
||||
<DefaultButton
|
||||
label={label}
|
||||
save={save}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`CustomSaveDraftButton.tsx`
|
||||
|
||||
```tsx
|
||||
import { CustomSaveDraftButtonProps } from 'payload/types'
|
||||
|
||||
export const CustomSaveDraftButton: CustomSaveDraftButtonProps = ({
|
||||
DefaultButton,
|
||||
@@ -182,8 +125,20 @@ export const CustomSaveDraftButton: CustomSaveDraftButtonProps = ({
|
||||
label,
|
||||
saveDraft,
|
||||
}) => {
|
||||
return <DefaultButton label={label} disabled={disabled} saveDraft={saveDraft} />
|
||||
return (
|
||||
<DefaultButton
|
||||
label={label}
|
||||
disabled={disabled}
|
||||
saveDraft={saveDraft}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`CustomPublishButton.tsx`
|
||||
|
||||
```tsx
|
||||
import { CustomPreviewButtonProps } from 'payload/types'
|
||||
|
||||
export const CustomPublishButton: CustomPublishButtonProps = ({
|
||||
DefaultButton,
|
||||
@@ -191,8 +146,20 @@ export const CustomPublishButton: CustomPublishButtonProps = ({
|
||||
label,
|
||||
publish,
|
||||
}) => {
|
||||
return <DefaultButton label={label} disabled={disabled} publish={publish} />
|
||||
return (
|
||||
<DefaultButton
|
||||
label={label}
|
||||
disabled={disabled}
|
||||
publish={publish}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`CustomPreviewButton`
|
||||
|
||||
```tsx
|
||||
import { CustomPreviewButtonProps } from 'payload/types'
|
||||
|
||||
export const CustomPreviewButton: CustomPreviewButtonProps = ({
|
||||
DefaultButton,
|
||||
@@ -200,8 +167,25 @@ export const CustomPreviewButton: CustomPreviewButtonProps = ({
|
||||
label,
|
||||
preview,
|
||||
}) => {
|
||||
return <DefaultButton label={label} disabled={disabled} preview={preview} />
|
||||
return (
|
||||
<DefaultButton
|
||||
label={label}
|
||||
disabled={disabled}
|
||||
preview={preview}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`collection.ts`
|
||||
|
||||
```tsx
|
||||
import * as React from 'react'
|
||||
|
||||
import { CustomSaveButton } from './CustomSaveButton'
|
||||
import { CustomSaveDraftButton } from './CustomSaveDraftButton'
|
||||
import { CustomPublishButton } from './CustomPublishButton'
|
||||
import { CustomPreviewButton } from './CustomPreviewButton'
|
||||
|
||||
export const MyCollection: SanitizedCollectionConfig = {
|
||||
slug: 'my-collection',
|
||||
@@ -214,87 +198,11 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
PreviewButton: CustomPreviewButton,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Collection views
|
||||
|
||||
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
|
||||
| **`List`** | The List view is used to show a list of documents for a given collection. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
|
||||
|
||||
```ts
|
||||
// Collection.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: MyCustomEditView,
|
||||
List: MyCustomListView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
|
||||
|
||||
**Customizing Nested Views within 'Edit' in Collections**
|
||||
|
||||
The `Edit` view in collections consists of several nested views, each serving a unique purpose. You can customize these nested views using the `admin.components.views.Edit` property in the collection's configuration. This approach allows you to replace specific nested views while keeping the overall structure of the `Edit` view intact, including the page breadcrumbs, title, tabs, etc.
|
||||
|
||||
Here's an example of how you can customize nested views within the `Edit` view in collections, including the use of the `actions` property:
|
||||
|
||||
```ts
|
||||
// Collection.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
Default: {
|
||||
Component: MyCustomDefaultTab,
|
||||
actions: [CollectionEditButton], // Custom actions for the default edit view
|
||||
},
|
||||
API: {
|
||||
Component: MyCustomAPIView,
|
||||
actions: [CollectionAPIButton], // Custom actions for API view
|
||||
},
|
||||
LivePreview: {
|
||||
Component: MyCustomLivePreviewView,
|
||||
actions: [CollectionLivePreviewButton], // Custom actions for Live Preview
|
||||
},
|
||||
Version: {
|
||||
Component: MyCustomVersionView,
|
||||
actions: [CollectionVersionButton], // Custom actions for Version view
|
||||
},
|
||||
Versions: {
|
||||
Component: MyCustomVersionsView,
|
||||
actions: [CollectionVersionsButton], // Custom actions for Versions view
|
||||
},
|
||||
},
|
||||
List: {
|
||||
actions: [CollectionListButton],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Adding New Tabs to 'Edit' View**
|
||||
|
||||
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
|
||||
|
||||
### Globals
|
||||
## Globals
|
||||
|
||||
As with Collections, you can override components on a global-by-global basis via the `admin.components` property.
|
||||
|
||||
@@ -304,359 +212,18 @@ As with Collections, you can override components on a global-by-global basis via
|
||||
| **`elements.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
|
||||
| **`elements.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
|
||||
| **`elements.PreviewButton`** | Replace the default `Preview` button with a custom component. |
|
||||
| **`views`** | Override or create new views within the Payload Admin UI. [More](#global-views) |
|
||||
|
||||
#### Global views
|
||||
|
||||
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
|
||||
|
||||
```ts
|
||||
// Global.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: MyCustomEditView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
|
||||
|
||||
**Customizing Nested Views within 'Edit' in Globals**
|
||||
|
||||
Similar to collections, Globals allow for detailed customization within the `Edit` view. This includes the ability to swap specific nested views while maintaining the overall structure of the `Edit` view. You can use the `admin.components.views.Edit` property in the Globals configuration to achieve this, and this will only replace the nested view, leaving the page breadcrumbs, title, and tabs intact.
|
||||
|
||||
Here's how you can customize nested views within the `Edit` view in Globals, including the use of the `actions` property:
|
||||
|
||||
```ts
|
||||
// Global.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
Default: {
|
||||
Component: MyCustomGlobalDefaultTab,
|
||||
actions: [GlobalEditButton], // Custom actions for the default edit view
|
||||
},
|
||||
API: {
|
||||
Component: MyCustomGlobalAPIView,
|
||||
actions: [GlobalAPIButton], // Custom actions for API view
|
||||
},
|
||||
LivePreview: {
|
||||
Component: MyCustomGlobalLivePreviewView,
|
||||
actions: [GlobalLivePreviewButton], // Custom actions for Live Preview
|
||||
},
|
||||
Version: {
|
||||
Component: MyCustomGlobalVersionView,
|
||||
actions: [GlobalVersionButton], // Custom actions for Version view
|
||||
},
|
||||
Versions: {
|
||||
Component: MyCustomGlobalVersionsView,
|
||||
actions: [GlobalVersionsButton], // Custom actions for Versions view
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
|
||||
|
||||
### Custom Tabs
|
||||
|
||||
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Default`** | The Default view is the primary view in which your document is edited. |
|
||||
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
|
||||
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
|
||||
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
|
||||
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
|
||||
|
||||
Here is an example:
|
||||
|
||||
```ts
|
||||
// Collection.ts or Global.ts
|
||||
export const MyCollection: SanitizedCollectionConfig = {
|
||||
slug: 'my-collection',
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: { // You can also define `components.views.Edit` as a component, this will override _all_ nested views
|
||||
Default: MyCustomDefaultTab,
|
||||
Versions: MyCustomVersionsTab,
|
||||
Version: MyCustomVersionTab,
|
||||
API: MyCustomAPITab,
|
||||
LivePreview: MyCustomLivePreviewTab,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
To add a _new_ tab to the `Edit` view, simply add another key to `components.views.Edit[key]` with at least a `path` and `Component` property. For example:
|
||||
|
||||
```ts
|
||||
// `Collection.ts` or `Global.ts`
|
||||
export const MyCollection: SanitizedCollectionConfig = {
|
||||
slug: 'my-collection',
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
MyCustomTab: {
|
||||
Component: MyCustomTab,
|
||||
path: '/my-custom-tab',
|
||||
// You an swap the entire tab component out for your own
|
||||
Tab: MyCustomTab
|
||||
},
|
||||
AnotherCustomView: {
|
||||
Component: AnotherCustomView,
|
||||
path: '/another-custom-view',
|
||||
// Or you can use the default tab component and just pass in your own label and href
|
||||
Tab: {
|
||||
label: 'Another Custom View',
|
||||
href: '/another-custom-view',
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Building a custom view component
|
||||
|
||||
Your custom view components will be given all the props that a React Router `<Route />` typically would receive, as well as two props from Payload:
|
||||
|
||||
| Prop | Description |
|
||||
| ----------------------- | ---------------------------------------------------------------------------- |
|
||||
| **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
|
||||
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the admin panel or not. |
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
It's up to you to secure your custom views. If your view requires a user to be logged in or to
|
||||
have certain access rights, you should handle that within your view component yourself.
|
||||
</Banner>
|
||||
|
||||
#### Example
|
||||
|
||||
You can find examples of custom views in the [Payload source code `/test/admin/components/views` folder](https://github.com/payloadcms/payload/tree/main/test/admin/components/views). There, you'll find two custom views:
|
||||
|
||||
1. A custom view that uses the `DefaultTemplate`, which is the built-in Payload template that displays the sidebar and "eyebrow nav"
|
||||
1. A custom view that uses the `MinimalTemplate` - which is just a centered template used for things like logging in or out
|
||||
|
||||
To see how to pass in your custom views to create custom views of your own, take a look at the `admin.components.views` property of the [Payload test admin config](https://github.com/payloadcms/payload/blob/main/test/admin/config.ts).
|
||||
|
||||
### Fields
|
||||
|
||||
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
Don't see a built-in field type that you need? Build it! Using a combination of custom validation
|
||||
and custom components, you can override the entirety of how a component functions within the admin
|
||||
panel and effectively create your own field type.
|
||||
</Banner>
|
||||
|
||||
**Fields support the following custom components:**
|
||||
|
||||
| Component | Description |
|
||||
| ------------ | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
|
||||
| **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) |
|
||||
| **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
|
||||
|
||||
As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text).
|
||||
|
||||
| Component | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Label`** | Override the default Label in the Field Component. [More](#label-component) |
|
||||
| **`Error`** | Override the default Label in the Field Component. [More](#error-component) |
|
||||
| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
|
||||
| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
|
||||
|
||||
## Cell Component
|
||||
|
||||
These are the props that will be passed to your custom Cell to use in your own components.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ----------------------------------------------------------------- |
|
||||
| **`field`** | An object that includes the field configuration. |
|
||||
| **`colIndex`** | A unique number for the column in the list. |
|
||||
| **`collection`** | An object with the config of the collection that the field is in. |
|
||||
| **`cellData`** | The data for the field that the cell represents. |
|
||||
| **`rowData`** | An object with all the field values for the row. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import type { Props } from 'payload/components/views/Cell'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'custom-cell'
|
||||
|
||||
const CustomCell: React.FC<Props> = (props) => {
|
||||
const { field, colIndex, collection, cellData, rowData } = props
|
||||
|
||||
return <span className={baseClass}>{cellData}</span>
|
||||
}
|
||||
```
|
||||
|
||||
## Field Component
|
||||
|
||||
When writing your own custom components you can make use of a number of hooks to set data, get reactive changes to other fields, get the id of the document or interact with a context from a custom provider.
|
||||
|
||||
### Sending and receiving values from the form
|
||||
|
||||
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
|
||||
|
||||
```tsx
|
||||
import { useField } from 'payload/components/forms'
|
||||
|
||||
type Props = { path: string }
|
||||
|
||||
const CustomTextField: React.FC<Props> = ({ path }) => {
|
||||
// highlight-start
|
||||
const { value, setValue } = useField<Props>({ path })
|
||||
// highlight-end
|
||||
|
||||
return <input onChange={(e) => setValue(e.target.value)} value={value.path} />
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
For more information regarding the hooks that are available to you while you build custom
|
||||
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
|
||||
</Banner>
|
||||
|
||||
## Label Component
|
||||
|
||||
These are the props that will be passed to your custom Label.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ---------------------------------------------------------------- |
|
||||
| **`htmlFor`** | Property used to set `for` attribute for label. |
|
||||
| **`label`** | Label value provided in field, it can be used with i18n. |
|
||||
| **`required`** | A boolean value that represents if the field is required or not. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { getTranslation } from 'payload/utilities/getTranslation'
|
||||
|
||||
type Props = {
|
||||
htmlFor?: string
|
||||
label?: Record<string, string> | false | string
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
const CustomLabel: React.FC<Props> = (props) => {
|
||||
const { htmlFor, label, required = false } = props
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
if (label) {
|
||||
return (<span>
|
||||
{getTranslation(label, i18n)}
|
||||
{required && <span className="required">*</span>}
|
||||
</span>);
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
## Error Component
|
||||
|
||||
These are the props that will be passed to your custom Error.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ------------------------------------------------------------- |
|
||||
| **`message`** | The error message. |
|
||||
| **`showError`** | A boolean value that represents if the error should be shown. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
message: string
|
||||
showError?: boolean
|
||||
}
|
||||
|
||||
const CustomError: React.FC<Props> = (props) => {
|
||||
const { message, showError } = props
|
||||
|
||||
if (showError) {
|
||||
return <p style={{color: 'red'}}>{message}</p>
|
||||
} else return null;
|
||||
}
|
||||
```
|
||||
|
||||
## afterInput and beforeInput
|
||||
|
||||
With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value.
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import { Field } from 'payload/types'
|
||||
|
||||
import './style.scss'
|
||||
|
||||
const ClearButton: React.FC = () => {
|
||||
return <button onClick={() => {/* ... */}}>X</button>
|
||||
}
|
||||
|
||||
const titleField: Field = {
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
admin: {
|
||||
components: {
|
||||
afterInput: [ClearButton]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default titleField;
|
||||
```
|
||||
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
|
||||
|
||||
## Custom providers
|
||||
|
||||
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the admin panel. Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. Read the [React context](https://reactjs.org/docs/context.html) docs to learn more.
|
||||
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the [Admin Panel](./overview). Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. See the [React Context](https://reactjs.org/docs/context.html) docs to learn more.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Reminder:</strong> Don't forget to pass the **children** prop through the provider
|
||||
component for the admin UI to show
|
||||
</Banner>
|
||||
|
||||
### Styling Custom Components
|
||||
## Styling Custom Components
|
||||
|
||||
Payload exports its SCSS variables and mixins for reuse in your own custom components. This is helpful in cases where you might want to style a custom input similarly to Payload's built-ini styling, so it blends more thoroughly into the existing admin UI.
|
||||
|
||||
@@ -666,23 +233,23 @@ To make use of Payload SCSS variables / mixins to use directly in your own compo
|
||||
@import '~payload/scss';
|
||||
```
|
||||
|
||||
### Getting the current language
|
||||
## Getting the current language
|
||||
|
||||
When developing custom components you can support multiple languages to be consistent with Payload's i18n support. The best way to do this is to add your translation resources to the [i18n configuration](https://payloadcms.com/docs/configuration/i18n) and import `useTranslation` from `react-i18next` in your components.
|
||||
When developing custom components you can support multiple languages to be consistent with Payload's i18n support. The best way to do this is to add your translation resources to the [i18n configuration](https://payloadcms.com/docs/configuration/i18n) and import `useTranslation` from `@payloadcms/ui/providers/Translation` in your components.
|
||||
|
||||
For example:
|
||||
|
||||
```tsx
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
|
||||
const CustomComponent: React.FC = () => {
|
||||
// highlight-start
|
||||
const { t, i18n } = useTranslation('namespace1')
|
||||
const { t, i18n } = useTranslation()
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<ul>
|
||||
<li>{t('key', { variable: 'value' })}</li>
|
||||
<li>{t('namespace1:key', { variable: 'value' })}</li>
|
||||
<li>{t('namespace2:key', { variable: 'value' })}</li>
|
||||
<li>{i18n.language}</li>
|
||||
</ul>
|
||||
@@ -690,7 +257,7 @@ const CustomComponent: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### Getting the current locale
|
||||
## Getting the current locale
|
||||
|
||||
In any custom component you can get the selected locale with `useLocale` hook. `useLocale` returns the full locale object, consisting of a `label`, `rtl`(right-to-left) property, and then `code`. Here is a simple example:
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Customizing CSS & SCSS
|
||||
label: Customizing CSS
|
||||
order: 40
|
||||
order: 60
|
||||
desc: Customize your Payload admin panel further by adding your own CSS or SCSS style sheet to the configuration, powerful theme and design options are waiting for you.
|
||||
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
### Adding your own CSS / SCSS
|
||||
## Adding your own CSS / SCSS
|
||||
|
||||
You can add your own CSS by providing your base Payload config with a path to your own CSS or SCSS. Customize the styling of any part of the Payload dashboard as necessary.
|
||||
|
||||
@@ -25,7 +25,7 @@ const config = buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
### Overriding built-in styles
|
||||
## Overriding built-in styles
|
||||
|
||||
To make it as easy as possible for you to override our styles, Payload uses [BEM naming conventions](http://getbem.com/) for all CSS within the Admin UI. If you provide your own CSS, you can override any built-in styles easily.
|
||||
|
||||
@@ -41,7 +41,7 @@ You can find the built-in Payload CSS variables within [`./src/admin/scss/app.sc
|
||||
- Fonts
|
||||
- Horizontal gutter
|
||||
|
||||
#### Dark mode
|
||||
### Dark mode
|
||||
|
||||
<Banner type="warning">
|
||||
If you're overriding colors or theme elevations, make sure to consider how your changes will
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
---
|
||||
title: Excluding server-only code from admin UI
|
||||
label: Excluding server code
|
||||
order: 70
|
||||
desc: Learn how to exclude server-only code from the Payload Admin UI bundle
|
||||
---
|
||||
|
||||
Because the Admin Panel browser bundle includes your Payload Config file, files using server-only modules need to be excluded.
|
||||
It's common for your config to rely on server only modules to perform logic in access control functions, hooks, and other contexts.
|
||||
|
||||
Any file that imports a server-only module such as `fs`, `stripe`, `authorizenet`, `nodemailer`, etc. **cannot** be included in the browser bundle.
|
||||
|
||||
#### Example Scenario
|
||||
|
||||
Say we have a collection called `Subscriptions` that has a `beforeChange` hook that creates a Stripe subscription whenever a Subscription document is created in Payload.
|
||||
|
||||
**Collection config**:
|
||||
|
||||
```ts
|
||||
// collections/Subscriptions/index.ts
|
||||
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
import createStripeSubscription from './hooks/createStripeSubscription'
|
||||
|
||||
export const Subscription: CollectionConfig = {
|
||||
slug: 'subscriptions',
|
||||
hooks: {
|
||||
beforeChange: [createStripeSubscription],
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'stripeSubscriptionID',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
**Collection hook**:
|
||||
|
||||
```ts
|
||||
// collections/Subscriptions/hooks/createStripeSubscription.ts
|
||||
|
||||
// highlight-start
|
||||
import Stripe from 'stripe' // <-- server-only module
|
||||
// highlight-end
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
|
||||
|
||||
export const createStripeSubscription = async ({ data, operation }) => {
|
||||
if (operation === 'create') {
|
||||
const dataWithStripeID = { ...data }
|
||||
|
||||
// use Stripe to create a Stripe subscription
|
||||
const subscription = await stripe.subscriptions.create({
|
||||
// Configure the subscription accordingly
|
||||
})
|
||||
|
||||
// Automatically add the Stripe subscription ID
|
||||
// to the data that will be saved to this Subscription doc
|
||||
dataWithStripeID.stripeSubscriptionID = subscription.id
|
||||
|
||||
return dataWithStripeID
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="error">
|
||||
<strong>Warning:</strong>
|
||||
<br />
|
||||
The above code is NOT production-ready and should not be referenced to create Stripe
|
||||
subscriptions. Although creating a beforeChange hook is a completely valid spot to do things like
|
||||
create subscriptions, the code above is incomplete and insecure, meant for explanation purposes
|
||||
only.
|
||||
</Banner>
|
||||
|
||||
**As-is, this collection will prevent your Admin panel from bundling or loading correctly, because Stripe relies on some Node-only packages.**
|
||||
|
||||
#### How to fix this
|
||||
|
||||
You need to make sure that you use `alias`es to tell your bundler to import "safe" files vs. attempting to import any server-side code that you need to get rid of. Depending on your bundler (Webpack, Vite, etc.) the steps involved may be slightly different.
|
||||
|
||||
The basic idea is to create a file that exports an empty object, and then alias import paths of any files that import server-only modules to that empty object file.
|
||||
|
||||
This way when your bundler goes to import a file that contains server-only modules, it will instead import the empty object file, which will not break the browser bundle.
|
||||
|
||||
### Aliasing server-only modules
|
||||
|
||||
To remove files that contain server-only modules from your bundle, you can use an `alias`.
|
||||
|
||||
In the Subscriptions config file above, we are importing the hook like so:
|
||||
|
||||
```ts
|
||||
// collections/Subscriptions/index.ts
|
||||
|
||||
import createStripeSubscription from './hooks/createStripeSubscription'
|
||||
```
|
||||
|
||||
By default the browser bundle will now include all the code from that file and any files down the tree. We know that the file imports `stripe`.
|
||||
|
||||
To fix this, we need to alias the `createStripeSubscription` file to a different file that can safely be included in the browser bundle.
|
||||
|
||||
First, we will create a mock file to replace the server-only file when bundling:
|
||||
```js
|
||||
// mocks/modules.js
|
||||
|
||||
export default {}
|
||||
|
||||
/**
|
||||
* NOTE: if you are destructuring an import
|
||||
* the mock file will need to export matching
|
||||
* variables as the destructured object.
|
||||
*
|
||||
* export const namedExport = {}
|
||||
*/
|
||||
```
|
||||
|
||||
Aliasing with [Webpack](/docs/admin/webpack) can be done by:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
|
||||
import { Subscriptions } from './collections/Subscriptions'
|
||||
|
||||
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
|
||||
const fullFilePath = path.resolve(
|
||||
__dirname,
|
||||
'collections/Subscriptions/hooks/createStripeSubscription'
|
||||
)
|
||||
|
||||
export default buildConfig({
|
||||
collections: [Subscriptions],
|
||||
admin: {
|
||||
bundler: webpackBundler(),
|
||||
webpack: (config) => {
|
||||
return {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
// highlight-start
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
[fullFilePath]: mockModulePath,
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Aliasing with [Vite](/docs/admin/vite) can be done by:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { viteBundler } from '@payloadcms/bundler-vite'
|
||||
|
||||
import { Subscriptions } from './collections/Subscriptions'
|
||||
|
||||
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
|
||||
|
||||
export default buildConfig({
|
||||
collections: [Subscriptions],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
|
||||
|
||||
// highlight-start
|
||||
// Add your own aliases using the find and replacement keys
|
||||
// remember, vite aliases are exact-match only
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
// highlight-end
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
194
docs/admin/fields.mdx
Normal file
194
docs/admin/fields.mdx
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
title: Customizing Fields
|
||||
label: Customizing Fields
|
||||
order: 40
|
||||
desc:
|
||||
keywords:
|
||||
---
|
||||
|
||||
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
Don't see a built-in field type that you need? Build it! Using a combination of custom validation
|
||||
and custom components, you can override the entirety of how a component functions within the admin
|
||||
panel and effectively create your own field type.
|
||||
</Banner>
|
||||
|
||||
**Fields support the following custom components:**
|
||||
|
||||
| Component | Description |
|
||||
| ------------ | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
|
||||
| **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) |
|
||||
| **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
|
||||
|
||||
As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text).
|
||||
|
||||
| Component | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Label`** | Override the default Label in the Field Component. [More](#label-component) |
|
||||
| **`Error`** | Override the default Label in the Field Component. [More](#error-component) |
|
||||
| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
|
||||
| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
|
||||
|
||||
## Cell Component
|
||||
|
||||
These are the props that will be passed to your custom Cell to use in your own components.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ----------------------------------------------------------------- |
|
||||
| **`field`** | An object that includes the field configuration. |
|
||||
| **`colIndex`** | A unique number for the column in the list. |
|
||||
| **`collection`** | An object with the config of the collection that the field is in. |
|
||||
| **`cellData`** | The data for the field that the cell represents. |
|
||||
| **`rowData`** | An object with all the field values for the row. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import type { Props } from 'payload/components/views/Cell'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'custom-cell'
|
||||
|
||||
const CustomCell: React.FC<Props> = (props) => {
|
||||
const { field, colIndex, collection, cellData, rowData } = props
|
||||
|
||||
return <span className={baseClass}>{cellData}</span>
|
||||
}
|
||||
```
|
||||
|
||||
## Field Component
|
||||
|
||||
When writing your own custom components you can make use of a number of hooks to set data, get reactive changes to other fields, get the id of the document or interact with a context from a custom provider.
|
||||
|
||||
### Sending and receiving values from the form
|
||||
|
||||
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
|
||||
|
||||
```tsx
|
||||
import { useField } from 'payload/components/forms'
|
||||
|
||||
const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
|
||||
// highlight-start
|
||||
const { value, setValue } = useField<string>({ path })
|
||||
// highlight-end
|
||||
|
||||
return <input onChange={(e) => setValue(e.target.value)} value={value} />
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
For more information regarding the hooks that are available to you while you build custom
|
||||
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
|
||||
</Banner>
|
||||
|
||||
## Label Component
|
||||
|
||||
These are the props that will be passed to your custom Label.
|
||||
|
||||
| Property | Description |
|
||||
| -------------- | ---------------------------------------------------------------- |
|
||||
| **`htmlFor`** | Property used to set `for` attribute for label. |
|
||||
| **`label`** | Label value provided in field, it can be used with i18n. |
|
||||
| **`required`** | A boolean value that represents if the field is required or not. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { getTranslation } from 'payload/utilities/getTranslation'
|
||||
|
||||
type Props = {
|
||||
htmlFor?: string
|
||||
label?: Record<string, string> | false | string
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
const CustomLabel: React.FC<Props> = (props) => {
|
||||
const { htmlFor, label, required = false } = props
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
if (label) {
|
||||
return (
|
||||
<span>
|
||||
{getTranslation(label, i18n)}
|
||||
{required && <span className="required">*</span>}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
## Error Component
|
||||
|
||||
These are the props that will be passed to your custom Error.
|
||||
|
||||
| Property | Description |
|
||||
| --------------- | ------------------------------------------------------------- |
|
||||
| **`message`** | The error message. |
|
||||
| **`showError`** | A boolean value that represents if the error should be shown. |
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
message: string
|
||||
showError?: boolean
|
||||
}
|
||||
|
||||
const CustomError: React.FC<Props> = (props) => {
|
||||
const { message, showError } = props
|
||||
|
||||
if (showError) {
|
||||
return <p style={{ color: 'red' }}>{message}</p>
|
||||
} else return null
|
||||
}
|
||||
```
|
||||
|
||||
## afterInput and beforeInput
|
||||
|
||||
With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value.
|
||||
|
||||
#### Example
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import { Field } from 'payload/types'
|
||||
|
||||
import './style.scss'
|
||||
|
||||
const ClearButton: React.FC = () => {
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
/* ... */
|
||||
}}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const titleField: Field = {
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
admin: {
|
||||
components: {
|
||||
afterInput: [ClearButton],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default titleField
|
||||
```
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: React Hooks
|
||||
label: React Hooks
|
||||
order: 30
|
||||
order: 50
|
||||
desc: Make use of all of the powerful React hooks that Payload provides.
|
||||
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload provides a variety of powerful hooks that can be used within your own React components. With them, you can interface with Payload itself and build just about any type of complex customization you can think of—directly in familiar React code.
|
||||
|
||||
### useField
|
||||
## useField
|
||||
|
||||
The `useField` hook is used internally within every applicable Payload field component, and it manages sending and receiving a field's state from its parent form.
|
||||
|
||||
@@ -52,7 +52,7 @@ const {
|
||||
// The rest of your component goes here
|
||||
```
|
||||
|
||||
### useFormFields
|
||||
## useFormFields
|
||||
|
||||
There are times when a custom field component needs to have access to data from other fields, and you have a few options to do so. The `useFormFields` hook is a powerful and highly performant way to retrieve a form's field state, as well as to retrieve the `dispatchFields` method, which can be helpful for setting other fields' form states from anywhere within a form.
|
||||
|
||||
@@ -81,7 +81,7 @@ const MyComponent: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### useAllFormFields
|
||||
## useAllFormFields
|
||||
|
||||
**To retrieve more than one field**, you can use the `useAllFormFields` hook. Your component will re-render when _any_ field changes, so use this hook only if you absolutely need to. Unlike the `useFormFields` hook, this hook does not accept a "selector", and it always returns an array with type of `[fields: Fields, dispatch: React.Dispatch<Action>]]`.
|
||||
|
||||
@@ -109,7 +109,7 @@ const ExampleComponent: React.FC = () => {
|
||||
};
|
||||
```
|
||||
|
||||
##### Updating other fields' values
|
||||
#### Updating other fields' values
|
||||
|
||||
If you are building a custom component, then you should use `setValue` which is returned from the `useField` hook to programmatically set your field's value. But if you're looking to update _another_ field's value, you can use `dispatchFields` returned from `useFormFields`.
|
||||
|
||||
@@ -128,7 +128,7 @@ You can send the following actions to the `dispatchFields` function.
|
||||
|
||||
To see types for each action supported within the `dispatchFields` hook, check out the Form types [here](https://github.com/payloadcms/payload/blob/main/packages/payload/src/admin/components/forms/Form/types.ts).
|
||||
|
||||
### useForm
|
||||
## useForm
|
||||
|
||||
The `useForm` hook can be used to interact with the form itself, and sends back many methods that can be used to reactively fetch form state without causing rerenders within your components each time a field is changed. This is useful if you have action-based callbacks that your components fire, and need to interact with form state _based on a user action_.
|
||||
|
||||
@@ -635,12 +635,44 @@ export const CustomArrayManager = () => {
|
||||
]}
|
||||
/>
|
||||
|
||||
### useDocumentInfo
|
||||
## useCollapsible
|
||||
|
||||
The `useCollapsible` hook allows you to control parent collapsibles:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------ | --- |
|
||||
| **`isCollapsed`** | State of the collapsible. `true` if open, `false` if collapsed |
|
||||
| **`isVisible`** | If nested, determine if the nearest collapsible is visible. `true` if no parent is closed, `false` otherwise |
|
||||
| **`toggle`** | Toggles the state of the nearest collapsible |
|
||||
| **`isWithinCollapsible`** | Determine when you are within another collaspible | |
|
||||
|
||||
**Example:**
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
|
||||
import { useCollapsible } from 'payload/components/utilities'
|
||||
|
||||
const CustomComponent: React.FC = () => {
|
||||
const { isCollapsed, toggle } = useCollapsible()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="field-type">I am {isCollapsed ? 'closed' : 'open'}</p>
|
||||
<button onClick={toggle} type="button">
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## useDocumentInfo
|
||||
|
||||
The `useDocumentInfo` hook provides lots of information about the document currently being edited, including the following:
|
||||
|
||||
| Property | Description |
|
||||
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`collection`** | If the doc is a collection, its collection config will be returned |
|
||||
| **`global`** | If the doc is a global, its global config will be returned |
|
||||
| **`id`** | If the doc is a collection, its ID will be returned |
|
||||
@@ -675,7 +707,7 @@ const LinkFromCategoryToPosts: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### useLocale
|
||||
## useLocale
|
||||
|
||||
In any custom component you can get the selected locale object with the `useLocale` hook. `useLocale`gives you the full locale object, consisting of a `label`, `rtl`(right-to-left) property, and then `code`. Here is a simple example:
|
||||
|
||||
@@ -696,7 +728,7 @@ const Greeting: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### useAuth
|
||||
## useAuth
|
||||
|
||||
Useful to retrieve info about the currently logged in user as well as methods for interacting with it. It sends back an object with the following properties:
|
||||
|
||||
@@ -723,7 +755,7 @@ const Greeting: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### useConfig
|
||||
## useConfig
|
||||
|
||||
Used to easily fetch the full Payload config.
|
||||
|
||||
@@ -739,7 +771,7 @@ const MyComponent: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### useEditDepth
|
||||
## useEditDepth
|
||||
|
||||
Sends back how many editing levels "deep" the current component is. Edit depth is relevant while adding new documents / editing documents in modal windows and other cases.
|
||||
|
||||
@@ -755,11 +787,39 @@ const MyComponent: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
### usePreferences
|
||||
## usePreferences
|
||||
|
||||
Returns methods to set and get user preferences. More info can be found [here](https://payloadcms.com/docs/admin/preferences).
|
||||
|
||||
### useTableColumns
|
||||
## useTheme
|
||||
|
||||
Returns the currently selected theme (`light`, `dark` or `auto`), a set function to update it and a boolean `autoMode`, used to determine if the theme value should be set automatically based on the user's device preferences.
|
||||
|
||||
```tsx
|
||||
import { useTheme } from 'payload/components/utilities'
|
||||
|
||||
const MyComponent: React.FC = () => {
|
||||
// highlight-start
|
||||
const { autoMode, setTheme, theme } = useTheme()
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>
|
||||
The current theme is {theme} and autoMode is {autoMode}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setTheme((prev) => (prev === 'light' ? 'dark' : 'light'))}
|
||||
>
|
||||
Toggle theme
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## useTableColumns
|
||||
|
||||
Returns methods to manipulate table columns
|
||||
|
||||
@@ -776,24 +836,21 @@ const MyComponent: React.FC = () => {
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetColumns}
|
||||
>
|
||||
<button type="button" onClick={resetColumns}>
|
||||
Reset columns
|
||||
</button>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### useDocumentEvents
|
||||
## useDocumentEvents
|
||||
|
||||
The `useDocumentEvents` hook provides a way of subscribing to cross-document events, such as updates made to nested documents within a drawer. This hook will report document events that are outside the scope of the document currently being edited. This hook provides the following:
|
||||
|
||||
| Property | Description |
|
||||
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`mostRecentUpdate`** | An object containing the most recently updated document. It contains the `entitySlug`, `id` (if collection), and `updatedAt` properties |
|
||||
| **`reportUpdate`** | A method used to report updates to documents. It accepts the same arguments as the `mostRecentUpdate` property. |
|
||||
| Property | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`mostRecentUpdate`** | An object containing the most recently updated document. It contains the `entitySlug`, `id` (if collection), and `updatedAt` properties |
|
||||
| **`reportUpdate`** | A method used to report updates to documents. It accepts the same arguments as the `mostRecentUpdate` property. |
|
||||
|
||||
**Example:**
|
||||
|
||||
@@ -803,14 +860,11 @@ import { useDocumentEvents } from 'payload/components/hooks'
|
||||
const ListenForUpdates: React.FC = () => {
|
||||
const { mostRecentUpdate } = useDocumentEvents()
|
||||
|
||||
return (
|
||||
<span>
|
||||
{JSON.stringify(mostRecentUpdate)}
|
||||
</span>
|
||||
)
|
||||
return <span>{JSON.stringify(mostRecentUpdate)}</span>
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future it will track more document-related events as needed, such as document creation, deletion, etc.
|
||||
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future
|
||||
it will track more document-related events as needed, such as document creation, deletion, etc.
|
||||
</Banner>
|
||||
|
||||
@@ -3,16 +3,15 @@ title: The Admin Panel
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Manage your data and customize the Admin Panel by swapping in your own React components. Create, modify or remove views, fields, styles and much more.
|
||||
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload dynamically generates a beautiful, fully functional React admin panel to manage your data. It's extremely powerful and can be customized / extended upon easily by swapping in your own React components. You can add additional views, modify how built-in views look / work, swap out Payload branding for your client's, build your own field types and much more.
|
||||
Payload dynamically generates a beautiful, fully functional Admin Panel to manage your users and data. The Payload Admin Panel is highly performant, even with 100+ fields, and is written fully in TypeScript. It is built with [React](https://react.dev) using the [Next.js App Router](https://nextjs.org/docs/app) and fully supports [React Server Components](https://react.dev/reference/rsc/server-components) which enables the use of the [Local API](/docs/local-api/overview) on the front-end.
|
||||
|
||||
The Payload Admin panel can be bundled with our officially supported [Vite](/docs/admin/vite) and [webpack](/docs/admin/webpack) bundlers or you can integrate another bundler following our adapter pattern approach.
|
||||
When bundled, it is code-split, highly performant (even with 100+ fields), and written fully in TypeScript.
|
||||
You can endlessly customize and extend the Admin UI by swapping your own in [Custom Components](./components) for everything from field labels to entire views. You can also modify built-in views, build your own fields, [swap out Payload branding for your own](https://payloadcms.com/blog/white-label-admin-ui), and so much more.
|
||||
|
||||
<Banner type="success">
|
||||
The Admin panel is meant to be simple enough to give you a starting point but not bring too much
|
||||
The Admin Panel is meant to be simple enough to give you a starting point but not bring too much
|
||||
complexity, so that you can easily customize it to suit the needs of your application and your
|
||||
editors.
|
||||
</Banner>
|
||||
@@ -20,44 +19,36 @@ When bundled, it is code-split, highly performant (even with 100+ fields), and w
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/admin.jpg"
|
||||
srcDark="https://payloadcms.com/images/docs/admin-dark.jpg"
|
||||
alt="Admin panel with collapsible sidebar"
|
||||
caption="Redesigned admin panel with a collapsible sidebar that's open by default, providing greater extensibility and enhanced horizontal real estate."
|
||||
alt="Admin Panel with collapsible sidebar"
|
||||
caption="Redesigned Admin Panel with a collapsible sidebar that's open by default, providing greater extensibility and enhanced horizontal real estate."
|
||||
/>
|
||||
|
||||
## Admin Options
|
||||
|
||||
All options for the Admin panel are defined in your base Payload config file.
|
||||
All high-level options for the Admin Panel are defined in your Payload config under the `admin` key:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `bundler` | The bundler that you would like to use to bundle the admin panel. Officially supported bundlers: [Webpack](/docs/admin/webpack) and [Vite](/docs/admin/vite). |
|
||||
| `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) |
|
||||
| `buildPath` | Specify an absolute path for where to store the built Admin panel bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
|
||||
| `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. |
|
||||
| `disable` | If set to `true`, the entire Admin panel will be disabled. |
|
||||
| `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/main/packages/payload/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. |
|
||||
| `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). |
|
||||
| `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
|
||||
| `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
|
||||
| `user` | The `slug` of a Collection that you want to be used to log in to the Admin Panel. [More](/docs/admin/overview#the-admin-user-collection) |
|
||||
| `buildPath` | Specify an absolute path for where to store the built Admin bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
|
||||
| `meta` | Base meta data to use for the Admin Panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per collection or per global basis. |
|
||||
| `disable` | If set to `true`, the entire Admin Panel will be disabled. |
|
||||
| `dateFormat` | Global date format that will be used for all dates in the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
|
||||
| `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
|
||||
| `autoLogin` | Used to automate admin log-in for dev and demonstration convenience. [More](/docs/authentication/config). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) |
|
||||
| `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) |
|
||||
| `vite` | Customize the Vite config that's used to generate the Admin panel. [More](/docs/admin/vite) |
|
||||
| `logoutRoute` | The route for the `logout` page. |
|
||||
| `inactivityRoute` | The route for the `logout` inactivity page. |
|
||||
| `components` | Component overrides that affect the entirety of the Admin Panel. [More](/docs/admin/components) |
|
||||
| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More](#custom-admin-panel-routes) |
|
||||
|
||||
### The Admin User Collection
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important:</strong>
|
||||
<br />
|
||||
The Payload Admin panel can only be used by one Collection that supports
|
||||
[Authentication](/docs/authentication/overview).
|
||||
The Admin Panel can only be used by a single auth-enabled Collection. To enable authentication for a Collection, simply set `auth: true` in the Collection's configuration. See [Authentication](/docs/authentication/overview) for more information.
|
||||
</Banner>
|
||||
|
||||
To specify which Collection to use to log in to the Admin panel, pass the `admin` options a `user` key equal to the slug of the Collection that you'd like to use.
|
||||
To specify which Collection to allow to login to the Admin Panel, pass the `admin.user` key equal to the slug of any auth-enabled Collection. See [Authentication](/docs/authentication/overview) for more information.
|
||||
|
||||
`payload.config.js`:
|
||||
|
||||
@@ -71,21 +62,67 @@ const config = buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
By default, if you have not specified a Collection, Payload will automatically provide you with a `User` Collection which will be used to access the Admin panel. You can customize or override the fields and settings of the default `User` Collection by passing your own collection using `users` as its `slug` to Payload. When this is done, Payload will use your provided `User` Collection instead of its default version.
|
||||
<Banner type="info">
|
||||
By default, if you have not specified a Collection, Payload will automatically provide a `User` Collection with access the Admin Panel. You can customize or override the fields and settings of the default `User` Collection by adding your own Collection with `slug: 'users'`. Doing this will force Payload to use your provided `User` Collection instead of its default version.
|
||||
</Banner>
|
||||
|
||||
**Note: you can use whatever Collection you'd like to access the Admin panel as long as the Collection supports Authentication. It doesn't need to be called `users`!**
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
You can use whatever Collection you'd like to access the Admin Panel as long as the Collection supports [Authentication](/docs/authentication/overview). It doesn't need to be called `users`. For example, you could use a Collection called `admins` or `editors` instead.
|
||||
</Banner>
|
||||
|
||||
For example, you may wish to have two Collections that both support `Authentication`:
|
||||
For example, you may wish to have two Collections that both support Authentication:
|
||||
|
||||
- `admins` - meant to have a higher level of permissions to manage your data and access the Admin panel
|
||||
- `customers` - meant for end users of your app that should not be allowed to log into the Admin panel
|
||||
- `admins` - meant to have a higher level of permissions to manage your data and access the Admin Panel
|
||||
- `customers` - meant for end users of your app that should not be allowed to log into the Admin Panel
|
||||
|
||||
This is totally possible. For the above scenario, by specifying `admin: { user: 'admins' }`, your Payload Admin panel will use `admins`. Any users logged in as `customers` will not be able to log in via the Admin panel.
|
||||
|
||||
### Light and dark modes
|
||||
|
||||
Users in the admin panel have access to choosing between light mode and dark mode for their editing experience. The setting is managed while logged into the admin UI within the user account page and will be stored with the browser. By default, the operating system preference is detected and used.
|
||||
This is totally possible. For the above scenario, by specifying `admin: { user: 'admins' }`, your Admin Panel will use `admins`. Any users logged in as `customers` will not be able to log in via the Admin Panel.
|
||||
|
||||
### Restricting user access
|
||||
|
||||
If you would like to restrict which users from a single Collection can access the Admin panel, you can use the `admin` access control function. [Click here](/docs/access-control/overview#admin) to learn more.
|
||||
It is also possible to allow _multiple admin user types_ into the Admin Panel with limited permissions. To do this, add a `roles` or similar field to your auth-enabled Collection and use the `access.admin` property to limit access. See [Access Control](/docs/access-control/overview) for full details. For a working example, check out the [Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth/payload).
|
||||
|
||||
### I18n
|
||||
|
||||
The Payload Admin Panel is translated in over 30 languages and counting. Languages are automatically detected based on the user's browser and all text displays in that language. If no language was detected, or if the user's language is not yet supported, English will be chosen. Users can easily specify their language by selecting one from their account page. See [I18n](../configuration/i18n) for more information.
|
||||
|
||||
<Banner>
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
If there is a language that Payload does not yet support, we accept code
|
||||
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
|
||||
</Banner>
|
||||
|
||||
### Light and dark modes
|
||||
|
||||
Users in the Admin Panel have access to choosing between light mode and dark mode for their editing experience. The setting is managed while logged into the admin UI within the user account page and will be stored with the browser. By default, the operating system preference is detected and used.
|
||||
|
||||
### Custom admin panel routes
|
||||
|
||||
You can configure custom routes in the Admin Panel for the following routes:
|
||||
|
||||
| Option | Default route |
|
||||
| ----------------- | ----------------------- |
|
||||
| `account` | `/account` |
|
||||
| `createFirstUser` | `/create-first-user` |
|
||||
| `forgot` | `/forgot` |
|
||||
| `inactivity` | `/logout-inactivity` |
|
||||
| `login` | `/login` |
|
||||
| `logout` | `/logout` |
|
||||
| `reset` | `/reset` |
|
||||
| `unauthorized` | `/unauthorized` |
|
||||
|
||||
`payload.config.js`:
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
|
||||
const config = buildConfig({
|
||||
admin: {
|
||||
routes: {
|
||||
admin: '/custom-admin-route'
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Managing User Preferences
|
||||
label: Preferences
|
||||
order: 50
|
||||
desc: Store the preferences of your users as they interact with the Admin panel.
|
||||
keywords: admin, preferences, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: admin, preferences, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
As your users interact with your Admin panel, you might want to store their preferences in a persistent manner, so that when they revisit the Admin panel, they can pick right back up where they left off.
|
||||
@@ -21,7 +21,7 @@ Out of the box, Payload handles the persistence of your users' preferences in a
|
||||
that is reading or setting a preference via all provided authentication methods.
|
||||
</Banner>
|
||||
|
||||
### Use cases
|
||||
## Use cases
|
||||
|
||||
This API is used significantly for internal operations of the Admin panel, as mentioned above. But, if you're building your own React components for use in the Admin panel, you can allow users to set their own preferences in correspondence to their usage of your components. For example:
|
||||
|
||||
@@ -30,7 +30,7 @@ This API is used significantly for internal operations of the Admin panel, as me
|
||||
- You might want to store `recentlyAccessed` documents to give admin editors an easy shortcut back to their recently accessed documents on the `Dashboard` or similar
|
||||
- Many other use cases exist. Invent your own! Give your editors an intelligent and persistent editing experience.
|
||||
|
||||
### Database
|
||||
## Database
|
||||
|
||||
Payload automatically creates an internally used `payload-preferences` collection that stores user preferences. Each document in the `payload-preferences` collection contains the following shape:
|
||||
|
||||
@@ -44,15 +44,15 @@ Payload automatically creates an internally used `payload-preferences` collectio
|
||||
| `createdAt` | A timestamp of when the preference was created. |
|
||||
| `updatedAt` | A timestamp set to the last time the preference was updated. |
|
||||
|
||||
### APIs
|
||||
## APIs
|
||||
|
||||
Preferences are available to both [GraphQL](/docs/graphql/overview#preferences) and [REST](/docs/rest-api/overview#) APIs.
|
||||
|
||||
### Adding or reading Preferences in your own components
|
||||
## Adding or reading Preferences in your own components
|
||||
|
||||
The Payload admin panel offers a `usePreferences` hook. The hook is only meant for use within the admin panel itself. It provides you with two methods:
|
||||
|
||||
##### `getPreference`
|
||||
#### `getPreference`
|
||||
|
||||
This async method provides an easy way to retrieve a user's preferences by `key`. It will return a promise containing the resulting preference value.
|
||||
|
||||
@@ -60,7 +60,7 @@ This async method provides an easy way to retrieve a user's preferences by `key`
|
||||
|
||||
- `key`: the `key` of your preference to retrieve.
|
||||
|
||||
##### `setPreference`
|
||||
#### `setPreference`
|
||||
|
||||
Also async, this method provides you with an easy way to set a user preference. It returns `void`.
|
||||
|
||||
|
||||
315
docs/admin/views.mdx
Normal file
315
docs/admin/views.mdx
Normal file
@@ -0,0 +1,315 @@
|
||||
---
|
||||
title: Customizing Views
|
||||
label: Customizing Views
|
||||
order: 30
|
||||
desc:
|
||||
keywords:
|
||||
---
|
||||
|
||||
### Root
|
||||
|
||||
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------- |
|
||||
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
|
||||
| **`Dashboard`** | The main landing page of the [Admin Panel](./overview). |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Account: MyCustomAccountView,
|
||||
Dashboard: MyCustomDashboardView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For more granular control, pass a configuration object instead. Payload exposes the following properties for each view:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
|
||||
| **`path`** \* | Any valid URL path or array of paths that [`path-to-regexp`](https://www.npmjs.com/package/path-to-regex) understands. |
|
||||
| **`exact`** | Boolean. When true, will only match if the path matches the `usePathname()` exactly. |
|
||||
| **`strict`** | When true, a path that has a trailing slash will only match a location.pathname with a trailing slash. This has no effect when there are additional URL segments in the location.pathname. |
|
||||
| **`sensitive`** | When true, will match if the path is case sensitive. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
#### Adding new root views
|
||||
|
||||
To add a _new_ view to the [Admin Panel](./overview), simply add another key to the `views` object with at least a `path` and `Component` property. For example:
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
MyCustomView: {
|
||||
Component: MyCustomView,
|
||||
path: '/my-custom-view',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
Routes are cascading. This means that unless explicitly given the `exact` property, they will
|
||||
match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all
|
||||
routes in your application. Alternatively, you could define your nested route _before_ your parent
|
||||
route.
|
||||
</Banner>
|
||||
|
||||
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components). For more examples regarding how to customize components, [look at the following examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
|
||||
|
||||
### Collections
|
||||
|
||||
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ---------- | ------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
|
||||
| **`List`** | The List view is used to show a list of documents for a given collection. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
|
||||
|
||||
```ts
|
||||
// Collection.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: MyCustomEditView,
|
||||
List: MyCustomListView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components).
|
||||
|
||||
**Customizing Nested Views within 'Edit' in Collections**
|
||||
|
||||
The `Edit` view in collections consists of several nested views, each serving a unique purpose. You can customize these nested views using the `admin.components.views.Edit` property in the collection's configuration. This approach allows you to replace specific nested views while keeping the overall structure of the `Edit` view intact, including the page breadcrumbs, title, tabs, etc.
|
||||
|
||||
Here's an example of how you can customize nested views within the `Edit` view in collections, including the use of the `actions` property:
|
||||
|
||||
```ts
|
||||
// Collection.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
Default: {
|
||||
Component: MyCustomDefaultTab,
|
||||
actions: [CollectionEditButton], // Custom actions for the default edit view
|
||||
},
|
||||
API: {
|
||||
Component: MyCustomAPIView,
|
||||
actions: [CollectionAPIButton], // Custom actions for API view
|
||||
},
|
||||
LivePreview: {
|
||||
Component: MyCustomLivePreviewView,
|
||||
actions: [CollectionLivePreviewButton], // Custom actions for Live Preview
|
||||
},
|
||||
Version: {
|
||||
Component: MyCustomVersionView,
|
||||
actions: [CollectionVersionButton], // Custom actions for Version view
|
||||
},
|
||||
Versions: {
|
||||
Component: MyCustomVersionsView,
|
||||
actions: [CollectionVersionsButton], // Custom actions for Versions view
|
||||
},
|
||||
},
|
||||
List: {
|
||||
actions: [CollectionListButton],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Adding New Tabs to 'Edit' View**
|
||||
|
||||
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
|
||||
|
||||
### Globals
|
||||
|
||||
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ---------- | ------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
|
||||
|
||||
```ts
|
||||
// Global.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: MyCustomEditView,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components).
|
||||
|
||||
**Customizing Nested Views within 'Edit' in Globals**
|
||||
|
||||
Similar to collections, Globals allow for detailed customization within the `Edit` view. This includes the ability to swap specific nested views while maintaining the overall structure of the `Edit` view. You can use the `admin.components.views.Edit` property in the Globals configuration to achieve this, and this will only replace the nested view, leaving the page breadcrumbs, title, and tabs intact.
|
||||
|
||||
Here's how you can customize nested views within the `Edit` view in Globals, including the use of the `actions` property:
|
||||
|
||||
```ts
|
||||
// Global.ts
|
||||
{
|
||||
// ...
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
Default: {
|
||||
Component: MyCustomGlobalDefaultTab,
|
||||
actions: [GlobalEditButton], // Custom actions for the default edit view
|
||||
},
|
||||
API: {
|
||||
Component: MyCustomGlobalAPIView,
|
||||
actions: [GlobalAPIButton], // Custom actions for API view
|
||||
},
|
||||
LivePreview: {
|
||||
Component: MyCustomGlobalLivePreviewView,
|
||||
actions: [GlobalLivePreviewButton], // Custom actions for Live Preview
|
||||
},
|
||||
Version: {
|
||||
Component: MyCustomGlobalVersionView,
|
||||
actions: [GlobalVersionButton], // Custom actions for Version view
|
||||
},
|
||||
Versions: {
|
||||
Component: MyCustomGlobalVersionsView,
|
||||
actions: [GlobalVersionsButton], // Custom actions for Versions view
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
|
||||
|
||||
### Custom Tabs
|
||||
|
||||
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Default`** | The Default view is the primary view in which your document is edited. |
|
||||
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
|
||||
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
|
||||
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
|
||||
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
|
||||
|
||||
Here is an example:
|
||||
|
||||
```ts
|
||||
// Collection.ts or Global.ts
|
||||
export const MyCollection: SanitizedCollectionConfig = {
|
||||
slug: 'my-collection',
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
// You can also define `components.views.Edit` as a component, this will override _all_ nested views
|
||||
Default: MyCustomDefaultTab,
|
||||
Versions: MyCustomVersionsTab,
|
||||
Version: MyCustomVersionTab,
|
||||
API: MyCustomAPITab,
|
||||
LivePreview: MyCustomLivePreviewTab,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
To add a _new_ tab to the `Edit` view, simply add another key to `components.views.Edit[key]` with at least a `path` and `Component` property. For example:
|
||||
|
||||
```ts
|
||||
// `Collection.ts` or `Global.ts`
|
||||
export const MyCollection: SanitizedCollectionConfig = {
|
||||
slug: 'my-collection',
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
MyCustomTab: {
|
||||
Component: MyCustomTab,
|
||||
path: '/my-custom-tab',
|
||||
// You an swap the entire tab component out for your own
|
||||
Tab: MyCustomTab,
|
||||
},
|
||||
AnotherCustomView: {
|
||||
Component: AnotherCustomView,
|
||||
path: '/another-custom-view',
|
||||
// Or you can use the default tab component and just pass in your own label and href
|
||||
Tab: {
|
||||
label: 'Another Custom View',
|
||||
href: '/another-custom-view',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Building Custom View Components
|
||||
|
||||
Your custom view components will be provided with the following props:
|
||||
|
||||
| Prop | Description |
|
||||
| ----------------------- | ---------------------------------------------------------------------------- |
|
||||
| **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
|
||||
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the [Admin Panel](./overview) or not. |
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
It's up to you to secure your custom views. If your view requires a user to be logged in or to
|
||||
have certain access rights, you should handle that within your view component yourself.
|
||||
</Banner>
|
||||
|
||||
### Examples
|
||||
|
||||
You can find examples of custom views in the [Payload source code `/test/admin/components/views` folder](https://github.com/payloadcms/payload/tree/main/test/admin/components/views). There, you'll find two custom views:
|
||||
|
||||
1. A custom view that uses the `DefaultTemplate`, which is the built-in Payload template that displays the sidebar and "eyebrow nav"
|
||||
1. A custom view that uses the `MinimalTemplate` - which is just a centered template used for things like logging in or out
|
||||
|
||||
To see how to pass in your custom views to create custom views of your own, take a look at the `admin.components.views` property of the [Payload test admin config](https://github.com/payloadcms/payload/blob/main/test/admin/config.ts).
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
---
|
||||
title: Vite
|
||||
label: Vite
|
||||
order: 90
|
||||
desc: NEEDS TO BE WRITTEN
|
||||
---
|
||||
|
||||
<Banner type="info">
|
||||
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
|
||||
</Banner>
|
||||
|
||||
Payload has a Vite bundler that you can install and bundle the Admin Panel with. This is an alternative to the [Webpack](/docs/admin/webpack) bundler and might give some performance boosts to your development workflow.
|
||||
|
||||
To use Vite as your bundler, first you need to install the package:
|
||||
|
||||
```bash
|
||||
yarn add @payloadcms/bundler-vite
|
||||
```
|
||||
|
||||
Then you will need to add the [bundler](/docs/admin/bundlers) to your Payload config:
|
||||
|
||||
```ts
|
||||
import { buildConfig } from '@payloadcms/config'
|
||||
import { viteBundler } from '@payloadcms/bundler-vite'
|
||||
|
||||
export default buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Vite works fundamentally differently than Webpack. In development mode, it will first pre-bundle any of your dependencies that are CommonJS-only, and then it'll leverage ESM directly in your browser for a better HMR experience.
|
||||
|
||||
It then uses Rollup to create production builds of your admin UI. With Vite, you should see a decent performance boost—especially after your first cold start. However, that first cold start might take a few more seconds.
|
||||
|
||||
<Banner type="warning">
|
||||
In most cases, Vite should work out of the box. But existing Payload plugins may need to make compatibility changes to support Vite.
|
||||
</Banner>
|
||||
|
||||
This is because Vite aliases work fundamentally differently than Webpack aliases, and Payload relies on aliasing server-only code out of the Payload config to ensure that the bundled admin JS works within your browser.
|
||||
|
||||
Here are the main differences between how Vite aliases work and how Webpack aliases work.
|
||||
|
||||
**Vite aliases do not work with absolute paths.**
|
||||
|
||||
In Vite, alias keys must <strong>exactly match</strong> a import paths. If you have 2 files that import the same server-only module, but have different import paths, you would need to add 2 aliases to support both import paths.
|
||||
|
||||
```ts
|
||||
// File A
|
||||
import serverOnlyModule from '../server-only-module'
|
||||
|
||||
// File B
|
||||
import serverOnlyModule from '../../server-only-module'
|
||||
|
||||
// payload.config.ts
|
||||
// You would need to add 2 aliases to support both import paths
|
||||
export const buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
|
||||
// Add your own aliases using the find and replacement keys
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
find: '../../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**Vite aliases do not get applied to pre-bundled dependencies.**
|
||||
|
||||
This especially affects plugins, as plugins will be pre-bundled by Vite using `esbuild`. To get around this and support Vite, plugin authors need to configure an alias to their plugin at the top level, so that the alias will work accordingly.
|
||||
|
||||
Here's an example. Say your plugin is called `payload-plugin-cool`. It's imported as follows:
|
||||
|
||||
```ts
|
||||
import { myCoolPlugin } from 'payload-plugin-cool'
|
||||
```
|
||||
|
||||
That plugin should create an alias to support Vite as follows:
|
||||
|
||||
```ts
|
||||
{
|
||||
// aliases go here
|
||||
find: 'payload-plugin-cool',
|
||||
replacement: path.resolve(__dirname, './my-admin-plugin.js')
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This will effectively alias the entire plugin and work with Vite. If the plugin requires admin-specific code, then the `./my-admin-plugin.js` alias target file should reflect any changes necessary to the admin UI that the main server-side plugin performs.
|
||||
|
||||
### Extending the Vite config
|
||||
|
||||
The Payload config supports a new property for plugins to be able to extend the Vite config specifically. That property exists on the main Payload config under `admin.vite`. You can check out the [Vite docs](https://vitejs.dev/config/shared-options.html) for more information on what you can do with the Vite config.
|
||||
|
||||
It's a function that takes a Vite config, and returns an updated Vite config. Here's an example:
|
||||
|
||||
```ts
|
||||
export const buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
|
||||
// Add your own aliases using the find and replacement keys
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Learn more about [aliasing server-only modules](https://payloadcms.com/docs/admin/excluding-server-code#aliasing-server-only-modules).
|
||||
|
||||
Even though there is a new property for Vite configs specifically, we have implemented some "compatibility" between Webpack and Vite out-of-the-box.
|
||||
|
||||
If your config specifies Webpack aliases, we attempt to leverage them automatically within the Vite config. They are merged into the Vite alias configuration seamlessly and may work out-of-the-box.
|
||||
@@ -1,67 +0,0 @@
|
||||
---
|
||||
title: Webpack
|
||||
label: Webpack
|
||||
order: 80
|
||||
desc: The Payload admin panel uses Webpack 5 and supports many common functionalities such as SCSS and Typescript out of the box to give you more freedom.
|
||||
keywords: admin, webpack, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
Payload has a Webpack (v5) bundler that you can build the Admin panel with. For now, we recommended using it because it is stable. If you are feeling a bit more adventurous you can give the [Vite](/docs/admin/vite) bundler a shot.
|
||||
|
||||
Out of the box, the Webpack bundler supports common functionalities such as SCSS and Typescript, but there are many cases where you may need to add support for additional functionalities.
|
||||
|
||||
#### Installation
|
||||
|
||||
```bash
|
||||
yarn add @payloadcms/bundler-webpack
|
||||
```
|
||||
|
||||
#### Import the bundler
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
|
||||
export default buildConfig({
|
||||
// highlight-start
|
||||
admin: {
|
||||
bundler: webpackBundler()
|
||||
},
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
### Extending Webpack
|
||||
|
||||
If you need to extend the Webpack config, you can do so by passing a function to the `admin.webpack` property on your Payload config.
|
||||
The function will receive the Webpack config as an argument and should return the modified config.
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
bundler: webpackBundler()
|
||||
// highlight-start
|
||||
webpack: (config) => {
|
||||
// full control of the Webpack config
|
||||
|
||||
return config
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
If changes to your Webpack aliases are not surfacing, they might be
|
||||
[cached](https://webpack.js.org/configuration/cache/) in `node_modules/.cache/webpack`. Try
|
||||
deleting that folder and restarting your server.
|
||||
</Banner>
|
||||
@@ -3,7 +3,7 @@ title: Authentication Config
|
||||
label: Config
|
||||
order: 20
|
||||
desc: Enable and customize options in the Authentication config for features including Forgot Password, Login Attempts, API key usage and more.
|
||||
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload's Authentication is extremely powerful and gives you everything you need when you go to build a new app or site in a secure and responsible manner.
|
||||
@@ -13,12 +13,12 @@ To enable Authentication on a collection, define an `auth` property and set it t
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) |
|
||||
| **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
|
||||
| **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
|
||||
| **`lockTime`** | Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
|
||||
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
|
||||
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
|
||||
| **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
|
||||
| **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
|
||||
| **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |
|
||||
@@ -49,7 +49,8 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
|
||||
<strong>Important:</strong>
|
||||
If you change your `PAYLOAD_SECRET`, you will need to regenerate your API keys.
|
||||
<br />
|
||||
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will no longer be valid.
|
||||
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will
|
||||
no longer be valid.
|
||||
</Banner>
|
||||
|
||||
#### Authenticating via API Key
|
||||
|
||||
@@ -3,12 +3,12 @@ title: Authentication Operations
|
||||
label: Operations
|
||||
order: 30
|
||||
desc: Enabling Authentication automatically makes key operations available such as Login, Logout, Verify, Unlock, Reset Password and more.
|
||||
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Enabling Authentication on a Collection automatically exposes additional auth-based operations in the Local, REST, and GraphQL APIs.
|
||||
|
||||
### Access
|
||||
## Access
|
||||
|
||||
The Access operation returns what a logged in user can and can't do with the collections and globals that are registered via your config. This data can be immensely helpful if your app needs to show and hide certain features based on access control, as the Payload Admin panel does.
|
||||
|
||||
@@ -69,7 +69,7 @@ query {
|
||||
|
||||
Document access can also be queried on a collection/global basis. Access on a global can queried like `http://localhost:3000/api/global-slug/access`, Collection document access can be queried like `http://localhost:3000/api/collection-slug/access/:id`.
|
||||
|
||||
### Me
|
||||
## Me
|
||||
|
||||
Returns either a logged in user with token or null when there is no logged in user.
|
||||
|
||||
@@ -105,9 +105,9 @@ query {
|
||||
}
|
||||
```
|
||||
|
||||
### Login
|
||||
## Login
|
||||
|
||||
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass an Express `res` to the Local API operation, Payload will set a cookie there as well.
|
||||
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass a `res` to the Local API operation, Payload will set a cookie there as well.
|
||||
|
||||
**Example REST API login**:
|
||||
|
||||
@@ -166,7 +166,7 @@ const result = await payload.login({
|
||||
})
|
||||
```
|
||||
|
||||
### Logout
|
||||
## Logout
|
||||
|
||||
As Payload sets HTTP-only cookies, logging out cannot be done by just removing a cookie in JavaScript, as HTTP-only cookies are inaccessible by JS within the browser. So, Payload exposes a `logout` operation to delete the token in a safe way.
|
||||
|
||||
@@ -189,7 +189,7 @@ mutation {
|
||||
}
|
||||
```
|
||||
|
||||
### Refresh
|
||||
## Refresh
|
||||
|
||||
Allows for "refreshing" JWTs. If your user has a token that is about to expire, but the user is still active and using the app, you might want to use the `refresh` operation to receive a new token by sending the operation the token that is about to expire.
|
||||
|
||||
@@ -244,7 +244,7 @@ mutation {
|
||||
`token` arg.
|
||||
</Banner>
|
||||
|
||||
### Verify by Email
|
||||
## Verify by Email
|
||||
|
||||
If your collection supports email verification, the Verify operation will be exposed which accepts a verification token and sets the user's `_verified` property to `true`, thereby allowing the user to authenticate with the Payload API.
|
||||
|
||||
@@ -276,7 +276,7 @@ const result = await payload.verifyEmail({
|
||||
})
|
||||
```
|
||||
|
||||
### Unlock
|
||||
## Unlock
|
||||
|
||||
If a user locks themselves out and you wish to deliberately unlock them, you can utilize the Unlock operation. The Admin panel features an Unlock control automatically for all collections that feature max login attempts, but you can programmatically unlock users as well by using the Unlock operation.
|
||||
|
||||
@@ -309,7 +309,7 @@ const result = await payload.unlock({
|
||||
})
|
||||
```
|
||||
|
||||
### Forgot Password
|
||||
## Forgot Password
|
||||
|
||||
Payload comes with built-in forgot password functionality. Submitting an email address to the Forgot Password operation will generate an email and send it to the respective email address with a link to reset their password.
|
||||
|
||||
@@ -361,7 +361,7 @@ const token = await payload.forgotPassword({
|
||||
use the token to "reset" their password.
|
||||
</Banner>
|
||||
|
||||
### Reset Password
|
||||
## Reset Password
|
||||
|
||||
After a user has "forgotten" their password and a token is generated, that token can be used to send to the reset password operation along with a new password which will allow the user to reset their password securely.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Authentication Overview
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Payload provides highly secure user Authentication out of the box, and you can fully customize, override, or remove the default Authentication support.
|
||||
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<YouTube
|
||||
@@ -30,7 +30,7 @@ _Admin panel screenshot depicting an Admins Collection with Auth enabled_
|
||||
|
||||
By default, Payload provides you with a `User` collection that supports Authentication, which is used to access the Admin panel. But, you can add support to one or many Collections of your own. For more information on how to customize, override, or remove the default `User` collection, [click here](/docs/admin/overview#the-admin-user-collection).
|
||||
|
||||
### Enabling Auth on a collection
|
||||
## Enabling Auth on a collection
|
||||
|
||||
Every Payload Collection can opt-in to supporting Authentication by specifying the `auth` property on the Collection's config to either `true` or to an object containing `auth` options.
|
||||
|
||||
@@ -57,12 +57,7 @@ export const Admins: CollectionConfig = {
|
||||
name: 'role',
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: [
|
||||
'user',
|
||||
'admin',
|
||||
'editor',
|
||||
'developer',
|
||||
],
|
||||
options: ['user', 'admin', 'editor', 'developer'],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -76,33 +71,33 @@ export const Admins: CollectionConfig = {
|
||||
|
||||
Once enabled, each document that is created within the Collection can be thought of as a `user` - who can make use of commonly required authentication functions such as logging in / out, resetting their password, and more.
|
||||
|
||||
### Logging in / out, resetting password, etc.
|
||||
## Logging in / out, resetting password, etc.
|
||||
|
||||
[Click here](/docs/authentication/operations) for a list of all automatically-enabled Auth operations, including `login`, `logout`, `refresh`, and others.
|
||||
|
||||
### Token-based auth
|
||||
## Token-based auth
|
||||
|
||||
Successfully logging in returns a `JWT` (JSON web token) which is how a user will identify themselves to Payload. By providing this JWT via either an HTTP-only cookie or an `Authorization: JWT` or `Authorization: Bearer` header, Payload will automatically identify the user and add its user JWT data to the Express `req`, which is available throughout Payload including within access control, hooks, and more.
|
||||
Successfully logging in returns a `JWT` (JSON web token) which is how a user will identify themselves to Payload. By providing this JWT via either an HTTP-only cookie or an `Authorization: JWT` or `Authorization: Bearer` header, Payload will automatically identify the user and add its user JWT data to the `req`, which is available throughout Payload including within access control, hooks, and more.
|
||||
|
||||
You can specify what data gets encoded to the JWT token by setting `saveToJWT` to true in your auth collection fields. If you wish to use a different key other than the field `name`, you can provide it to `saveToJWT` as a string. It is also possible to use `saveToJWT` on fields that are nested in inside groups and tabs. If a group has a `saveToJWT` set it will include the object with all sub-fields in the token. You can set `saveToJWT: false` for any fields you wish to omit. If a field inside a group has `saveToJWT` set, but the group does not, the field will be included at the top level of the token.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
You can access the logged-in user from access control functions and hooks via the Express{' '}
|
||||
You can access the logged-in user from access control functions and hooks via the{' '}
|
||||
<strong>req</strong>. The logged-in user is automatically added as the <strong>user</strong>{' '}
|
||||
property.
|
||||
</Banner>
|
||||
|
||||
### HTTP-only cookies
|
||||
## HTTP-only cookies
|
||||
|
||||
Payload `login`, `logout`, and `refresh` operations make use of HTTP-only cookies for authentication purposes. HTTP-only cookies are a highly secure method of storing identifiable data on a user's device so that Payload can automatically recognize a returning user until their cookie expires. They are totally protected from common XSS attacks and cannot be read at all via JavaScript in the browser.
|
||||
|
||||
##### Automatic browser inclusion
|
||||
#### Automatic browser inclusion
|
||||
|
||||
Modern browsers automatically include `http-only` cookies when making requests directly to URLs—meaning that if you are running your API on http://example.com, and you have logged in and visit http://example.com/test-page, your browser will automatically include the Payload authentication cookie for you.
|
||||
|
||||
##### Using Fetch or other HTTP APIs
|
||||
#### Using Fetch or other HTTP APIs
|
||||
|
||||
However, if you use `fetch` or similar APIs to retrieve Payload resources from its REST or GraphQL API, you need to specify to include credentials (cookies).
|
||||
|
||||
@@ -126,7 +121,7 @@ For more about how to automatically include cookies in requests from your app to
|
||||
will still show HTTP-only cookies, even when JavaScript running on the page can't.
|
||||
</Banner>
|
||||
|
||||
### CSRF Protection
|
||||
## CSRF Protection
|
||||
|
||||
CSRF (cross-site request forgery) attacks are common and dangerous. By using an HTTP-only cookie, Payload removes many XSS vulnerabilities, however, CSRF attacks can still be possible.
|
||||
|
||||
@@ -164,7 +159,7 @@ const config = buildConfig({
|
||||
export default config
|
||||
```
|
||||
|
||||
### Identifying users via the Authorization Header
|
||||
## Identifying users via the Authorization Header
|
||||
|
||||
In addition to authenticating via an HTTP-only cookie, you can also identify users via the `Authorization` header on an HTTP request.
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
title: Using the Payload Auth Middleware
|
||||
label: Using the Middleware
|
||||
order: 40
|
||||
desc: Make full use of Payload's built-in authentication with your own custom Express endpoints by adding Payload's authentication middleware.
|
||||
keywords: authentication, middleware, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
Because Payload uses your existing Express server, you are free to add whatever logic you need to your app through endpoints of your own. However, Payload does not add its middleware to your Express app itself—instead, it scopes all of its middleware to Payload-specific routers.
|
||||
|
||||
This approach has a ton of benefits - it's great for isolation of concerns and limiting scope, but it also means that your additional routes won't have access to Payload's user authentication.
|
||||
|
||||
<Banner type="success">
|
||||
You can make full use of Payload's built-in authentication within your own custom Express
|
||||
endpoints by adding Payload's authentication middleware.
|
||||
</Banner>
|
||||
|
||||
<Banner type="warning">
|
||||
Payload must be initialized before the `payload.authenticate` middleware can be used. This is done
|
||||
by calling `payload.init()` prior to adding the middleware.
|
||||
</Banner>
|
||||
|
||||
Example in `server.js`:
|
||||
|
||||
```ts
|
||||
import express from 'express'
|
||||
import payload from 'payload'
|
||||
|
||||
const app = express()
|
||||
|
||||
const start = async () => {
|
||||
await payload.init({
|
||||
secret: 'PAYLOAD_SECRET_KEY',
|
||||
express: app,
|
||||
})
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
// Note: Payload must be initialized before the `payload.authenticate` middleware can be used
|
||||
router.use(payload.authenticate) // highlight-line
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
if (req.user) {
|
||||
return res.send(`Authenticated successfully as ${req.user.email}.`)
|
||||
}
|
||||
|
||||
return res.send('Not authenticated')
|
||||
})
|
||||
|
||||
app.use('/some-route-here', router)
|
||||
|
||||
app.listen(3000)
|
||||
}
|
||||
|
||||
start()
|
||||
```
|
||||
@@ -6,7 +6,7 @@ desc: Quickly configure and deploy your Payload Cloud project in a few simple st
|
||||
keywords: configuration, config, settings, project, cloud, payload cloud, deploy, deployment
|
||||
---
|
||||
|
||||
### Select your plan
|
||||
## Select your plan
|
||||
|
||||
Once you have created a project, you will need to select your plan. This will determine the resources that are allocated to your project and the features that are available to you.
|
||||
|
||||
@@ -17,7 +17,7 @@ Once you have created a project, you will need to select your plan. This will de
|
||||
anytime.
|
||||
</Banner>
|
||||
|
||||
### Project Details
|
||||
## Project Details
|
||||
|
||||
| Option | Description |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -26,7 +26,7 @@ Once you have created a project, you will need to select your plan. This will de
|
||||
| **Project Slug** | Choose a unique slug to identify your project. This needs to be unique for your team and you can change it any time. |
|
||||
| **Team** | Select the team you want to create the project under. If this is your first project, a personal team will be created for you automatically. You can modify your team settings and invite new members at any time from the Team Settings page. |
|
||||
|
||||
### Build Settings
|
||||
## Build Settings
|
||||
|
||||
If you are deploying a new project from a template, the following settings will be automatically configured for you. If you are using your own repository, you need to make sure your build settings are accurate for your project to deploy correctly.
|
||||
|
||||
@@ -39,17 +39,17 @@ If you are deploying a new project from a template, the following settings will
|
||||
| **Branch to Deploy** | Select the branch of your repository that you want to deploy from. This is the branch that will be used to build your project when you commit new changes. |
|
||||
| **Default Domain** | Set a default domain for your project. This must be unique and you will not able to change it. You can always add a custom domain later in your project settings. |
|
||||
|
||||
### Environment Variables
|
||||
## Environment Variables
|
||||
|
||||
Any of the features in Payload Cloud that require environment variables will automatically be provided to your application. If your app requires any custom environment variables, you can set them here.
|
||||
|
||||
<Banner type="warning">
|
||||
Note: For security reasons, any variables you wish to provide to the Admin panel must be prefixed
|
||||
with `PAYLOAD_PUBLIC_`. Learn more
|
||||
[here](https://payloadcms.com/docs/admin/webpack#admin-environment-vars).
|
||||
[here](https://payloadcms.com/docs/admin/environment-vars).
|
||||
</Banner>
|
||||
|
||||
### Payment
|
||||
## Payment
|
||||
|
||||
Payment methods can be set per project and can be updated any time. You can use team’s default payment method, or add a new one. Modify your payment methods in your Project settings / Team settings.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ desc: Manage your Payload Cloud projects.
|
||||
keywords: cloud, payload cloud, projects, project, overview, database, file storage, build settings, environment variables, custom domains, email, developing locally
|
||||
---
|
||||
|
||||
### Overview
|
||||
## Overview
|
||||
|
||||
<Banner>
|
||||
The overview tab shows your most recent deployment, along with build and deployment logs. From
|
||||
@@ -18,33 +18,53 @@ keywords: cloud, payload cloud, projects, project, overview, database, file stor
|
||||

|
||||
_A screenshot of the Overview page for a Cloud project._
|
||||
|
||||
### Database
|
||||
## Database
|
||||
|
||||
Your Payload Cloud project comes with a MongoDB serverless Atlas DB instance or a Dedicated Atlas cluster, depending on your plan. To interact with your cloud database, you will be provided with a MongoDB connection string. This can be found under the **Database** tab of your project.
|
||||
|
||||
`mongodb+srv://your_connection_string`
|
||||
|
||||
### File Storage
|
||||
## File Storage
|
||||
|
||||
Payload Cloud gives you S3 file storage backed by Cloudflare as a CDN, and this plugin extends Payload so that all of your media will be stored in S3 rather than locally.
|
||||
|
||||
AWS Cognito is used for authentication to your S3 bucket. The [Payload Cloud Plugin](https://github.com/payloadcms/plugin-cloud) will automatically pick up these values. These values are only if you'd like to access your files directly, outside of Payload Cloud.
|
||||
|
||||
### Build Settings
|
||||
### Accessing Files Outside of Payload Cloud
|
||||
|
||||
If you'd like to access your files outside of Payload Cloud, you'll need to retrieve some values from your project's settings and put them into your environment variables. In Payload Cloud, navigate to the File Storage tab and copy the values using the copy button. Put these values in your .env file. Also copy the Cognito Password value separately and put into your .env file as well.
|
||||
|
||||
When you are done, you should have the following values in your .env file:
|
||||
|
||||
```env
|
||||
PAYLOAD_CLOUD=true
|
||||
PAYLOAD_CLOUD_ENVIRONMENT=prod
|
||||
PAYLOAD_CLOUD_COGNITO_USER_POOL_CLIENT_ID=
|
||||
PAYLOAD_CLOUD_COGNITO_USER_POOL_ID=
|
||||
PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID=
|
||||
PAYLOAD_CLOUD_PROJECT_ID=
|
||||
PAYLOAD_CLOUD_BUCKET=
|
||||
PAYLOAD_CLOUD_BUCKET_REGION=
|
||||
PAYLOAD_CLOUD_COGNITO_PASSWORD=
|
||||
```
|
||||
|
||||
The plugin will pick up these values and use them to access your files.
|
||||
|
||||
## Build Settings
|
||||
|
||||
You can update settings from your Project’s Settings tab. Changes to your build settings will trigger a redeployment of your project.
|
||||
|
||||
### Environment Variables
|
||||
## Environment Variables
|
||||
|
||||
From the Environment Variables page of the Settings tab, you can add, update and delete variables for use in your project. Like build settings, these changes will trigger a redeployment of your project.
|
||||
|
||||
<Banner>
|
||||
Note: For security reasons, any variables you wish to provide to the Admin panel must be prefixed
|
||||
with `PAYLOAD_PUBLIC_`. Learn more
|
||||
[here](https://payloadcms.com/docs/admin/webpack#admin-environment-vars).
|
||||
[here](https://payloadcms.com/docs/admin/environment-vars).
|
||||
</Banner>
|
||||
|
||||
### Custom Domains
|
||||
## Custom Domains
|
||||
|
||||
With Payload Cloud, you can add custom domain names to your project. To do so, first go to the Domains page of the Settings tab of your project. Here you can see your default domain. To add a new domain, type in the domain name you wish to use.
|
||||
|
||||
@@ -64,19 +84,19 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
### Email
|
||||
## Email
|
||||
|
||||
Powered by [Resend](https://resend.com), Payload Cloud comes with integrated email support out of the box. No configuration is needed, and you can use `payload.sendEmail()` to send email right from your Payload app. To learn more about sending email with Payload, checkout the [Email Configuration](https://payloadcms.com/docs/email/overview) overview.
|
||||
|
||||
If you are on the Pro or Enterprise plan, you can add your own custom Email domain name. From the Email page of your project’s Settings, add the domain you wish to use for email delivery. This will generate a set of DNS records. Add these records to your DNS provider and click verify to check that your records are resolving properly. Once verified, your emails will now be sent from your custom domain name.
|
||||
|
||||
### Developing Locally
|
||||
## Developing Locally
|
||||
|
||||
To make changes to your project, you will need to clone the repository defined in your project settings to your local machine. In order to run your project locally, you will need configure your local environment first. Refer to your repository’s `README.md` file to see the steps needed for your specific template.
|
||||
|
||||
From there, you are ready to make updates to your project. When you are ready to make your changes live, commit your changes to the branch you specified in your Project settings, and your application will automatically trigger a redeploy and build from your latest commit.
|
||||
|
||||
### Cloud Plugin
|
||||
## Cloud Plugin
|
||||
|
||||
Projects generated from a template will come pre-configured with the official Cloud Plugin, but if you are using your own repository you will need to add this into your project. To do so, add the plugin to your Payload config:
|
||||
|
||||
@@ -97,7 +117,7 @@ export default buildConfig({
|
||||
over Payload Cloud's email service.
|
||||
</Banner>
|
||||
|
||||
##### **Optional configuration**
|
||||
#### **Optional configuration**
|
||||
|
||||
If you wish to opt-out of any Payload cloud features, the plugin also accepts options to do so.
|
||||
|
||||
|
||||
@@ -14,22 +14,22 @@ keywords: team, teams, billing, subscription, payment, plan, plans, cloud, paylo
|
||||

|
||||
_A screenshot of the Team Settings page._
|
||||
|
||||
### Members
|
||||
## Members
|
||||
|
||||
Each team has members that can interact with your projects. You can invite multiple people to your team and each individual can belong to more than one team. You can assign them either `owner` or `user` permissions. Owners are able to make admin-only changes, such as deleting projects, and editing billing information.
|
||||
|
||||
### Adding Members
|
||||
## Adding Members
|
||||
|
||||
To add a new member to your team, visit your Team’s Settings page, and click “Invite Teammate”. You can then add their email address, and assign their role. Press “Save” to send the invitations, which will send an email to the invited team member where they can create a new account.
|
||||
|
||||
### Billing
|
||||
## Billing
|
||||
|
||||
Users can update billing settings and subscriptions for any teams where they are designated as an `owner`. To make updates to the team’s payment methods, visit the Billing page under the Team Settings tab. You can add new cards, delete cards, and set a payment method as a default. The default payment method will be used in the event that another payment method fails.
|
||||
|
||||
### Subscriptions
|
||||
## Subscriptions
|
||||
|
||||
From the Subscriptions page, a team owner can see all current plans for their team. From here, you can see the price of each plan, if there is an active trial, and when you will be billed next.
|
||||
|
||||
### Invoices
|
||||
## Invoices
|
||||
|
||||
The Invoices page will you show you the invoices for your account, as well as the status on their payment.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Collection Configs
|
||||
label: Collections
|
||||
order: 20
|
||||
desc: Structure your Collections for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks, setting timestamps and more.
|
||||
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload Collections are defined through configs of their own, and you can define as many as your application needs. Each
|
||||
@@ -13,27 +13,29 @@ It's often best practice to write your Collections in separate files and then im
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
|
||||
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
|
||||
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
|
||||
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
|
||||
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
|
||||
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/upload/overview) documentation. |
|
||||
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
|
||||
| **`versions`** | Set to true to enable default options, or configure with object properties. [More](/docs/versions/overview#collection-config) |
|
||||
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`defaultSort`** | Pass a top-level field to sort by default in the collection List view. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
|
||||
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
|
||||
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
|
||||
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
|
||||
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
|
||||
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/upload/overview) documentation. |
|
||||
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
|
||||
| **`versions`** | Set to true to enable default options, or configure with object properties. [More](/docs/versions/overview#collection-config) |
|
||||
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`disableDuplicate`** | When true, do not show the "Duplicate" button while editing documents within this collection and prevent `duplicate` from all APIs. |
|
||||
| **`defaultSort`** | Pass a top-level field to sort by default in the collection List view. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
|
||||
| **`dbName`** | Custom table or collection name depending on the database adapter. Auto-generated from slug if not defined.
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
#### Simple collection example
|
||||
### Simple collection example
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
@@ -56,36 +58,36 @@ export const Orders: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
#### More collection config examples
|
||||
### More collection config examples
|
||||
|
||||
You can find an assortment
|
||||
of [example collection configs](https://github.com/payloadcms/public-demo/tree/master/src/payload/collections) in the Public
|
||||
Demo source code on GitHub.
|
||||
|
||||
### Admin options
|
||||
## Admin options
|
||||
|
||||
You can customize the way that the Admin panel behaves on a collection-by-collection basis by defining the `admin`
|
||||
property on a collection's config.
|
||||
|
||||
| Option | Description |
|
||||
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
|
||||
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
|
||||
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
|
||||
| `description` | Text or React component to display below the Collection label in the List view to give editors more information. |
|
||||
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
|
||||
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
| `enableRichTextLink` | The [Rich Text](/docs/fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `meta` | Metadata overrides to apply to the [Admin panel](../admin/overview). Included properties are `description` and `openGraph`. |
|
||||
| `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](#preview). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) |
|
||||
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More](#list-searchable-fields) |
|
||||
| **`pagination`** | Set pagination-specific options for this collection. [More](#pagination) |
|
||||
|
||||
### Preview
|
||||
## Preview
|
||||
|
||||
Collection `admin` options can accept a `preview` function that will be used to generate a link pointing to the frontend
|
||||
of your app to preview data.
|
||||
@@ -124,32 +126,32 @@ export const Posts: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Pagination
|
||||
## Pagination
|
||||
|
||||
Here are a few options that you can specify options for pagination on a collection-by-collection basis:
|
||||
|
||||
| Option | Description |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------|
|
||||
| -------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
|
||||
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List view. |
|
||||
|
||||
### Access control
|
||||
## Access control
|
||||
|
||||
You can specify extremely granular access control (what users can do with documents in a collection) on a collection by
|
||||
collection basis. To learn more, go to the [Access Control](/docs/access-control/overview) docs.
|
||||
|
||||
### Hooks
|
||||
## Hooks
|
||||
|
||||
Hooks are a powerful way to extend collection functionality and execute your own logic, and can be defined on a
|
||||
collection by collection basis. To learn more, go to the [Hooks](/docs/hooks/overview) documentation.
|
||||
|
||||
### Field types
|
||||
## Field types
|
||||
|
||||
Collections support all field types that Payload has to offer—including simple fields like text and checkboxes all the
|
||||
way to more complicated layout-building field groups like Blocks. [Click here](/docs/fields/overview) to learn more
|
||||
about field types.
|
||||
|
||||
### List Searchable Fields
|
||||
## List Searchable Fields
|
||||
|
||||
In the List view, there is a "search" box that allows you to quickly find a document with a search. By default, it
|
||||
searches on the ID field. If you have `admin.useAsTitle` defined, the list search will use that field. However, you can
|
||||
@@ -167,54 +169,7 @@ those three fields plus the ID field.
|
||||
so your admin queries can remain performant.
|
||||
</Banner>
|
||||
|
||||
### Admin Hooks
|
||||
|
||||
In addition to collection hooks themselves, Payload provides for admin UI-specific hooks that you can leverage.
|
||||
|
||||
**`beforeDuplicate`**
|
||||
|
||||
The `beforeDuplicate` hook is an async function that accepts an object containing the data to duplicate, as well as the
|
||||
locale of the doc to duplicate. Within this hook, you can modify the data to be duplicated, which is useful in cases
|
||||
where you have unique fields that need to be incremented or similar, as well as if you want to automatically modify a
|
||||
document's `title`.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
import { BeforeDuplicate, CollectionConfig } from 'payload/types'
|
||||
// Your auto-generated Page type
|
||||
import { Page } from '../payload-types.ts'
|
||||
|
||||
const beforeDuplicate: BeforeDuplicate<Page> = ({ data }) => {
|
||||
return {
|
||||
...data,
|
||||
title: `${data.title} Copy`,
|
||||
uniqueField: data.uniqueField ? `${data.uniqueField}-copy` : '',
|
||||
}
|
||||
}
|
||||
|
||||
export const Page: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
admin: {
|
||||
hooks: {
|
||||
beforeDuplicate,
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'uniqueField',
|
||||
type: 'text',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
## TypeScript
|
||||
|
||||
You can import collection types as follows:
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
---
|
||||
title: Express
|
||||
label: Express
|
||||
order: 60
|
||||
desc: Payload utilizes Express middleware packages, you can customize how they work by passing in configuration options.
|
||||
keywords: config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
Payload utilizes a few Express-specific middleware packages within its own routers. You can customize how they work by passing in configuration options to the main Payload config's `express` property.
|
||||
|
||||
### Custom Middleware
|
||||
|
||||
Payload allows you to pass in custom Express middleware to be used on all of the routes it opens. This is useful for adding logging or any other custom functionality to your endpoints.
|
||||
|
||||
There are 2 exposed properties. Each property is an array of middleware functions.
|
||||
|
||||
- `preMiddleware` - runs before any of the Payload middleware
|
||||
- `postMiddleware` - runs after all of the Payload middleware
|
||||
|
||||
```ts
|
||||
{
|
||||
express: {
|
||||
preMiddleware: [
|
||||
(req, res, next) => {
|
||||
// do something
|
||||
next()
|
||||
}
|
||||
],
|
||||
postMiddleware: [
|
||||
(req, res, next) => {
|
||||
// do something
|
||||
next()
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Example logging middleware function
|
||||
const requestLoggerMiddleware = (req, res, next) => {
|
||||
req.payload.logger.info(`request: ${req.method} ${req.url}`)
|
||||
next()
|
||||
}
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
`express.json()` is used to parse JSON body content into JavaScript objects accessible on the Express `req`. Payload allows you to customize all of the `json` method's options. Common examples of customization use-cases are increasing the max allowed JSON body size which defaults to `2MB`.
|
||||
|
||||
**Example payload.config.js for how to increase the max JSON size allowed to be sent to Payload endpoints:**
|
||||
|
||||
```js
|
||||
{
|
||||
express: {
|
||||
json: {
|
||||
limit: '4mb',
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can find a list of all available options that are able to be passed to `express.json()` [here](https://expressjs.com/en/api.html).
|
||||
|
||||
### Compression
|
||||
|
||||
Payload uses the `compression` package to optimize transfer size for all of the routes it opens, and you can pass customization options through the Payload config.
|
||||
|
||||
To customize compression options, pass an object to the Payload config's `express` property.
|
||||
|
||||
**Example payload.config.js:**
|
||||
|
||||
```js
|
||||
{
|
||||
express: {
|
||||
compression: {
|
||||
// settings go here
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Typically, the default options for this package are suitable. However, for a list of all available customization options, [click here](http://expressjs.com/en/resources/middleware/compression.html).
|
||||
@@ -3,7 +3,7 @@ title: Global Configs
|
||||
label: Globals
|
||||
order: 30
|
||||
desc: Set up your Global config for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks and more.
|
||||
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Global configs are in many ways similar to [Collections](/docs/configuration/collections). The big difference is that Collections will potentially contain _many_ documents, while a Global is a "one-off". Globals are perfect for things like header nav, site-wide banner alerts, app-wide localized strings, and other "global" data that your site or app might rely on.
|
||||
@@ -26,10 +26,11 @@ As with Collection configs, it's often best practice to write your Globals in se
|
||||
| **`graphQL.name`** | Text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`dbName`** | Custom table or collection name for this global depending on the database adapter. Auto-generated from slug if not defined.
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
#### Simple Global example
|
||||
### Simple Global example
|
||||
|
||||
```ts
|
||||
import { GlobalConfig } from 'payload/types'
|
||||
@@ -57,24 +58,25 @@ const Nav: GlobalConfig = {
|
||||
export default Nav
|
||||
```
|
||||
|
||||
#### Global config example
|
||||
### Global config example
|
||||
|
||||
You can find a few [example Global configs](https://github.com/payloadcms/public-demo/tree/master/src/payload/globals) in the Public Demo source code on GitHub.
|
||||
|
||||
### Admin options
|
||||
## Admin options
|
||||
|
||||
You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a Global's config.
|
||||
|
||||
| Option | Description |
|
||||
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
|
||||
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
|
||||
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
|
||||
| `livePreview`| Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
| Option | Description |
|
||||
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
|
||||
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
|
||||
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
| `meta` | Metadata overrides to apply to the [Admin panel](../admin/overview). Included properties are `description` and `openGraph`. |
|
||||
|
||||
### Preview
|
||||
## Preview
|
||||
|
||||
Global `admin` options can accept a `preview` function that will be used to generate a link pointing to the frontend of your app to preview data.
|
||||
|
||||
@@ -111,19 +113,19 @@ export const MyGlobal: GlobalConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Access control
|
||||
## Access control
|
||||
|
||||
As with Collections, you can specify extremely granular access control (what users can do with this Global) on a Global-by-Global basis. However, Globals only have `update` and `read` access control due to their nature of only having one document. To learn more, go to the [Access Control](/docs/access-control/overview) docs.
|
||||
|
||||
### Hooks
|
||||
## Hooks
|
||||
|
||||
Globals also fully support a smaller subset of Hooks. To learn more, go to the [Hooks](/docs/hooks/overview) documentation.
|
||||
|
||||
### Field types
|
||||
## Field types
|
||||
|
||||
Globals support all field types that Payload has to offer—including simple fields like text and checkboxes all the way to more complicated layout-building field groups like Blocks. [Click here](/docs/fields/overview) to learn more about field types.
|
||||
|
||||
### TypeScript
|
||||
## TypeScript
|
||||
|
||||
You can import global types as follows:
|
||||
|
||||
|
||||
@@ -3,12 +3,43 @@ title: I18n
|
||||
label: I18n
|
||||
order: 40
|
||||
desc: Manage and customize internationalization support in your CMS editor experience
|
||||
keywords: internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Not only does Payload support managing localized content, it also has internationalization support so that admin users can work in their preferred language. Payload's i18n support is built on top of [i18next](https://www.i18next.com). It comes included by default and can be extended in your config.
|
||||
Not only does Payload support managing localized content, it also has internationalization support so that users in the [Admin Panel](../admin/overview) can work in their preferred language. Payload's i18n comes by default without any additional setup, and you can extend the default settings to customize the language settings to your needs.
|
||||
|
||||
While Payload's built-in features come translated, you may want to also translate parts of your project's configuration too. This is possible in places like collections and globals labels and groups, field labels, descriptions and input placeholder text. The admin UI will display all the correct translations you provide based on the user's language.
|
||||
### Configuration Options
|
||||
|
||||
In your Payload config, you can add translations and customize the settings in `i18n`. Payload will use your custom options and merge it with the default, allowing you to override the settings Payload provides.
|
||||
|
||||
**Example Payload config extending i18n:**
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
|
||||
export default buildConfig({
|
||||
//...
|
||||
i18n: {
|
||||
fallbackLng: 'en', // default
|
||||
debug: false, // default
|
||||
resources: {
|
||||
en: {
|
||||
custom: {
|
||||
// namespace can be anything you want
|
||||
key1: 'Translation with {{variable}}', // translation
|
||||
},
|
||||
// override existing translation keys
|
||||
general: {
|
||||
dashboard: 'Home',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
While Payload's built-in features come translated, you may want to also translate parts of your project's configuration too. This is possible in places like Collections and Globals labels and groups, field labels, descriptions and input placeholder text. The admin UI will display all the correct translations you provide based on the user's language.
|
||||
|
||||
Here is an example of a simple collection supporting both English and Spanish editors:
|
||||
|
||||
@@ -56,9 +87,9 @@ export const Articles: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Admin UI
|
||||
## Admin UI
|
||||
|
||||
The Payload admin panel reads the language settings of a user's browser and display all text in that language, or will fall back to English if the user's language is not yet supported.
|
||||
The [Admin Panel](../admin/overview) reads the language settings of a user's browser and display all text in that language, or will fall back to English if the user's language is not yet supported.
|
||||
After a user logs in, they can change their language selection in the `/account` view.
|
||||
|
||||
<Banner>
|
||||
@@ -68,15 +99,13 @@ After a user logs in, they can change their language selection in the `/account`
|
||||
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
|
||||
</Banner>
|
||||
|
||||
### Node Express
|
||||
## Node
|
||||
|
||||
Payload's backend uses express middleware to set the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
|
||||
Payload's backend sets the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
|
||||
|
||||
Anywhere in your Payload app that you have access to the `req` object, you can access i18next's extensive internationalization features assigned to `req.i18n`. To access text translations you can use `req.t('namespace:key')`.
|
||||
Anywhere in your Payload app that you have access to the `req` object, you can access payload's extensive internationalization features assigned to `req.i18n`. To access text translations you can use `req.t('namespace:key')`.
|
||||
|
||||
Read the i18next [API documentation](https://www.i18next.com/overview/api) to learn more.
|
||||
|
||||
### Configuration Options
|
||||
## Configuration Options
|
||||
|
||||
In your Payload config, you can add translations and customize the settings in `i18n`. Payload will use your custom options and merge it with the default, allowing you to override the settings Payload provides.
|
||||
|
||||
@@ -88,9 +117,8 @@ import { buildConfig } from 'payload/config'
|
||||
export default buildConfig({
|
||||
//...
|
||||
i18n: {
|
||||
fallbackLng: 'en', // default
|
||||
debug: false, // default
|
||||
resources: {
|
||||
fallbackLanguage: 'en', // default
|
||||
translations: {
|
||||
en: {
|
||||
custom: {
|
||||
// namespace can be anything you want
|
||||
@@ -107,4 +135,63 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
See the i18next [configuration options](https://www.i18next.com/overview/configuration-options) to learn more.
|
||||
## Types for custom translations
|
||||
|
||||
In order to use custom translations in your project, you need to provide the types for the translations. Here is an example of how you can define the types for the custom translations in a custom react component:
|
||||
|
||||
```ts
|
||||
'use client'
|
||||
import type { NestedKeysStripped } from '@payloadcms/translations'
|
||||
import type React from 'react'
|
||||
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
|
||||
const customTranslations = {
|
||||
en: {
|
||||
general: {
|
||||
test: 'Custom Translation',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type CustomTranslationObject = typeof customTranslations.en
|
||||
type CustomTranslationKeys = NestedKeysStripped<CustomTranslationObject>
|
||||
|
||||
export const MyComponent: React.FC = () => {
|
||||
const { i18n, t } = useTranslation<CustomTranslationObject, CustomTranslationKeys>() // These generics merge your custom translations with the default client translations
|
||||
|
||||
return t('general:test')
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Additionally, payload exposes the `t` function in various places, for example in labels. Here is how you would type those:
|
||||
|
||||
```ts
|
||||
import type {
|
||||
DefaultTranslationKeys,
|
||||
NestedKeysStripped,
|
||||
TFunction,
|
||||
} from '@payloadcms/translations'
|
||||
import type { Field } from 'payload/types'
|
||||
|
||||
const customTranslations = {
|
||||
en: {
|
||||
general: {
|
||||
test: 'Custom Translation',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type CustomTranslationObject = typeof customTranslations.en
|
||||
type CustomTranslationKeys = NestedKeysStripped<CustomTranslationObject>
|
||||
|
||||
const field: Field = {
|
||||
name: 'myField',
|
||||
type: 'text',
|
||||
label: (
|
||||
{ t }: { t: TFunction<CustomTranslationKeys | DefaultTranslationKeys> }, // The generic passed to TFunction does not automatically merge the custom translations with the default translations. We need to merge them ourselves here
|
||||
) => t('fields:addLabel'),
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -3,14 +3,16 @@ title: Localization
|
||||
label: Localization
|
||||
order: 50
|
||||
desc: Add and maintain as many locales as you need by adding Localization to your Payload config, set options for default locale, fallbacks, fields and more.
|
||||
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All localization support is opt-in by default. To do so, follow the two steps below.
|
||||
Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All
|
||||
localization support is opt-in by default. To do so, follow the two steps below.
|
||||
|
||||
### Enabling in the Payload config
|
||||
## Enabling in the Payload config
|
||||
|
||||
Add the `localization` property to your Payload config to enable localization project-wide. You'll need to provide a list of all locales that you'd like to support as well as set a few other options.
|
||||
Add the `localization` property to your Payload config to enable localization project-wide. You'll need to provide a
|
||||
list of all locales that you'd like to support as well as set a few other options.
|
||||
|
||||
**Example Payload config set up for localization:**
|
||||
|
||||
@@ -47,7 +49,8 @@ export default buildConfig({
|
||||
{
|
||||
label: 'Arabic',
|
||||
code: 'ar',
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left) when current locale is rtl
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left)
|
||||
// when current locale is rtl
|
||||
rtl: true,
|
||||
},
|
||||
],
|
||||
@@ -57,7 +60,8 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
**Example Payload config set up for localization with full locales objects (including [internationalization](/docs/configuration/i18n) support):**
|
||||
**Example Payload config set up for localization with full locales objects (
|
||||
including [internationalization](/docs/configuration/i18n) support):**
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
@@ -93,19 +97,38 @@ export default buildConfig({
|
||||
|
||||
**`locales`**
|
||||
|
||||
Array-based list of all locales that you would like to support. These can be strings of locale codes or objects with a `label`, a locale `code`, and the `rtl` (right-to-left) property. The locale codes do not need to be in any specific format. It's up to you to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter language and country codes (ISO 3166‑1) such as `en-US`, `en-UK`, `es-MX`, etc.
|
||||
Array-based list of all the languages that you would like to support. This can be an array containing strings for each
|
||||
language code you want your project to store and serve or objects with a `label`, a locale `code`, `rtl` (
|
||||
right-to-left), and `fallbackLocale` property. The locale codes do not need to be in any specific format. It's up to you
|
||||
to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter
|
||||
language and country codes (ISO 3166‑1) such as `en-US`, `en-UK`, `es-MX`, etc.
|
||||
|
||||
## Locale Object Properties
|
||||
|
||||
| Option | Description |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale` |
|
||||
| **`label`** | A string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use. |
|
||||
| **`rtl`** | A boolean that when true will make the admin UI display in Right-To-Left. |
|
||||
| **`fallbackLocale`** | The code for this language to fallback to when properties of a document are not present. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
**`defaultLocale`**
|
||||
|
||||
Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale.
|
||||
Required string that matches one of the locale codes from the array provided. By default, if no locale is specified,
|
||||
documents will be returned in this locale.
|
||||
|
||||
**`fallback`**
|
||||
|
||||
Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated.
|
||||
Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a
|
||||
localized value corresponding to the requested locale, then if this property is enabled, the document will automatically
|
||||
fall back to the fallback locale value. If this property is not enabled, the value will not be populated.
|
||||
|
||||
### Field by field localization
|
||||
## Field by field localization
|
||||
|
||||
Payload localization works on a **field** level—not a document level. In addition to configuring the base Payload config to support localization, you need to specify each field that you would like to localize.
|
||||
Payload localization works on a **field** level—not a document level. In addition to configuring the base Payload config
|
||||
to support localization, you need to specify each field that you would like to localize.
|
||||
|
||||
**Here is an example of how to enable localization for a field:**
|
||||
|
||||
@@ -119,9 +142,11 @@ Payload localization works on a **field** level—not a document level. In addit
|
||||
}
|
||||
```
|
||||
|
||||
With the above configuration, the `title` field will now be saved in the database as an object of all locales instead of a single string.
|
||||
With the above configuration, the `title` field will now be saved in the database as an object of all locales instead of
|
||||
a single string.
|
||||
|
||||
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s and `block`s.
|
||||
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s
|
||||
and `block`s.
|
||||
|
||||
<Banner>
|
||||
<strong>Note:</strong>
|
||||
@@ -141,11 +166,12 @@ All field types with a `name` property support the `localized` property—even t
|
||||
strategy.
|
||||
</Banner>
|
||||
|
||||
### Retrieving localized docs
|
||||
## Retrieving localized docs
|
||||
|
||||
When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be used.
|
||||
When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be
|
||||
used.
|
||||
|
||||
##### REST API
|
||||
#### REST API
|
||||
|
||||
REST API locale functionality relies on URL query parameters.
|
||||
|
||||
@@ -155,7 +181,8 @@ Specify your desired locale by providing the `locale` query parameter directly i
|
||||
|
||||
**`?fallback-locale=`**
|
||||
|
||||
Specify fallback locale to be used by providing the `fallback-locale` query parameter. This can be provided as either a valid locale as provided to your base Payload config, or `'null'`, `'false'`, or `'none'` to disable falling back.
|
||||
Specify fallback locale to be used by providing the `fallback-locale` query parameter. This can be provided as either a
|
||||
valid locale as provided to your base Payload config, or `'null'`, `'false'`, or `'none'` to disable falling back.
|
||||
|
||||
**Example:**
|
||||
|
||||
@@ -163,11 +190,13 @@ Specify fallback locale to be used by providing the `fallback-locale` query para
|
||||
fetch('https://localhost:3000/api/pages?locale=es&fallback-locale=none');
|
||||
```
|
||||
|
||||
##### GraphQL API
|
||||
#### GraphQL API
|
||||
|
||||
In the GraphQL API, you can specify `locale` and `fallbackLocale` args to all relevant queries and mutations.
|
||||
|
||||
The `locale` arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious to see how locales are auto-formatted, you can use the [GraphQL playground](/docs/graphql/overview#graphql-playground).
|
||||
The `locale` arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum
|
||||
values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious
|
||||
to see how locales are auto-formatted, you can use the [GraphQL playground](/docs/graphql/overview#graphql-playground).
|
||||
|
||||
The `fallbackLocale` arg will accept valid locales as well as `none` to disable falling back.
|
||||
|
||||
@@ -189,9 +218,11 @@ query {
|
||||
arguments in nested related document queries.
|
||||
</Banner>
|
||||
|
||||
##### Local API
|
||||
#### Local API
|
||||
|
||||
You can specify `locale` as well as `fallbackLocale` within the Local API as well as properties on the `options` argument. The `locale` property will accept any valid locale, and the `fallbackLocale` property will accept any valid locale as well as `'null'`, `'false'`, `false`, and `'none'`.
|
||||
You can specify `locale` as well as `fallbackLocale` within the Local API as well as properties on the `options`
|
||||
argument. The `locale` property will accept any valid locale, and the `fallbackLocale` property will accept any valid
|
||||
locale as well as `'null'`, `'false'`, `false`, and `'none'`.
|
||||
|
||||
**Example:**
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: The Payload Config
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: The Payload config is central to everything that Payload does, from adding custom React components, to modifying collections, controlling localization and much more.
|
||||
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload is a _config-based_, code-first CMS and application framework. The Payload config is central to everything that Payload does. It scaffolds the data that Payload stores as well as maintains custom React components, hook logic, custom validations, and much more.
|
||||
@@ -13,59 +13,52 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
|
||||
<Banner type="warning">
|
||||
<strong>Important:</strong>
|
||||
<br />
|
||||
This file is included in the Payload admin bundle, so make sure you do not embed any sensitive
|
||||
The serializable portions of this config are included in the Payload Admin bundle, so make sure you do not embed any sensitive
|
||||
information.
|
||||
</Banner>
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `admin` \* | Base Payload admin configuration. Specify bundler*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
|
||||
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
|
||||
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
|
||||
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |
|
||||
| `collections` | An array of all Collections that Payload will manage. To read more about how to define your collection configs, [click here](/docs/configuration/collections). |
|
||||
| `globals` | An array of all Globals that Payload will manage. For more on Globals and their configs, [click here](/docs/configuration/globals). |
|
||||
| `cors` | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
|
||||
| `localization` | Opt-in and control how Payload handles the translation of your content into multiple locales. [More](/docs/configuration/localization) |
|
||||
| `graphQL` | Manage GraphQL-specific functionality here. Define your own queries and mutations, manage query complexity limits, and [more](/docs/graphql/overview#graphql-options). |
|
||||
| `cookiePrefix` | A string that will be prefixed to all cookies that Payload sets. |
|
||||
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
||||
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
||||
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||
| `indexSortableFields` | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
||||
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
||||
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
||||
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
||||
| `express` | Express-specific middleware options such as compression and JSON parsing. [More](/docs/configuration/express) |
|
||||
| `debug` | Enable to expose more detailed error information. |
|
||||
| `telemetry` | Disable Payload telemetry by passing `false`. [More](/docs/configuration/overview#telemetry) |
|
||||
| `rateLimit` | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and [more](/docs/production/preventing-abuse#rate-limiting-requests). |
|
||||
| `hooks` | Tap into Payload-wide hooks. [More](/docs/hooks/overview) |
|
||||
| `plugins` | An array of Payload plugins. [More](/docs/plugins/overview) |
|
||||
| `endpoints` | An array of custom API endpoints added to the Payload router. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| `custom` | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `admin` \* | Base Payload admin configuration. Specify, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
|
||||
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
|
||||
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
|
||||
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |
|
||||
| `collections` | An array of all Collections that Payload will manage. To read more about how to define your collection configs, [click here](/docs/configuration/collections). |
|
||||
| `globals` | An array of all Globals that Payload will manage. For more on Globals and their configs, [click here](/docs/configuration/globals). |
|
||||
| `cors` | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
|
||||
| `localization` | Opt-in and control how Payload handles the translation of your content into multiple locales. [More](/docs/configuration/localization) |
|
||||
| `graphQL` | Manage GraphQL-specific functionality here. Define your own queries and mutations, manage query complexity limits, and [more](/docs/graphql/overview#graphql-options). |
|
||||
| `cookiePrefix` | A string that will be prefixed to all cookies that Payload sets. |
|
||||
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
||||
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
||||
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||
| `indexSortableFields` | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
||||
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
||||
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
||||
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
||||
| `debug` | Enable to expose more detailed error information. |
|
||||
| `telemetry` | Disable Payload telemetry by passing `false`. [More](/docs/configuration/overview#telemetry) |
|
||||
| `rateLimit` | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and [more](/docs/production/preventing-abuse#rate-limiting-requests). |
|
||||
| `hooks` | Tap into Payload-wide hooks. [More](/docs/hooks/overview) |
|
||||
| `plugins` | An array of Payload plugins. [More](/docs/plugins/overview) |
|
||||
| `endpoints` | An array of custom API endpoints added to the Payload router. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| `custom` | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
#### Simple example
|
||||
### Simple example
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
||||
import { postgresAdapter } from '@payloadcms/db-postgres' // beta
|
||||
|
||||
import { viteBundler } from '@payloadcms/bundler-vite'
|
||||
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
|
||||
import { lexicalEditor } from '@payloadcms/richtext-lexical' // beta
|
||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
bundler: webpackBundler(), // or viteBundler()
|
||||
},
|
||||
db: mongooseAdapter({}) // or postgresAdapter({}),
|
||||
editor: lexicalEditor({}) // or slateEditor({})
|
||||
collections: [
|
||||
@@ -106,11 +99,11 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
#### Full example config
|
||||
### Full example config
|
||||
|
||||
You can see a full [example config](https://github.com/payloadcms/public-demo/blob/master/src/payload/payload.config.ts) in the Public Demo source code on GitHub.
|
||||
|
||||
### Using environment variables in your config
|
||||
## Using environment variables in your config
|
||||
|
||||
We suggest using the `dotenv` package to handle environment variables alongside of Payload. All that's necessary to do is to require the package as high up in your application as possible (for example, at the top of your `server.js` file), and ensure that it can find an `.env` file that you create.
|
||||
|
||||
@@ -139,10 +132,10 @@ project-name
|
||||
<br />
|
||||
If you use an environment variable to configure any properties that are required for the Admin
|
||||
panel to function (ex. serverURL or any routes), you need to make sure that your Admin panel code
|
||||
can access it. [Click here](/docs/admin/webpack#admin-environment-vars) for more info.
|
||||
can access it. [Click here](/docs/admin/environment-vars) for more info.
|
||||
</Banner>
|
||||
|
||||
### Customizing & Automating Config Location Detection
|
||||
## Customizing & Automating Config Location Detection
|
||||
|
||||
Payload is designed to automatically locate your configuration file. By default, it will first look in the root of your current working directory for a file named `payload.config.js` or `payload.config.ts` if you're using TypeScript.
|
||||
|
||||
@@ -152,7 +145,7 @@ In production mode, Payload will first attempt to find the config file in the ou
|
||||
|
||||
Please ensure your `tsconfig.json` is properly configured if you want Payload to accurately auto-detect your configuration file location. If `tsconfig.json` does not exist or doesn't specify `rootDir` or `outDir`, Payload will default to the current working directory.
|
||||
|
||||
#### Overriding the Config Location
|
||||
### Overriding the Config Location
|
||||
|
||||
In addition to the above automated detection, you can specify your own location for the Payload config file. This is done by using the environment variable `PAYLOAD_CONFIG_PATH`. The path you provide via this environment variable can either be absolute or relative to your current working directory. This can be useful in situations where your Payload config is not in a standard location, or you wish to switch between multiple configurations.
|
||||
|
||||
@@ -168,11 +161,11 @@ In addition to the above automated detection, you can specify your own location
|
||||
|
||||
When `PAYLOAD_CONFIG_PATH` is set, Payload will use this path to load the configuration, bypassing all automated detection.
|
||||
|
||||
### Developing within the Config
|
||||
## Developing within the Config
|
||||
|
||||
Payload comes with `isomorphic-fetch` installed which means that even in Node, you can use the `fetch` API just as you would within the browser. No need to import `axios` or similar, unless you want to!
|
||||
|
||||
### TypeScript
|
||||
## TypeScript
|
||||
|
||||
You can import config types as follows:
|
||||
|
||||
@@ -190,7 +183,7 @@ import { SanitizedConfig } from 'payload/config'
|
||||
// Generally, this is only used internally by Payload.
|
||||
```
|
||||
|
||||
### Telemetry
|
||||
## Telemetry
|
||||
|
||||
Payload collects **completely anonymous** telemetry data about general usage. This data is super important to us and helps us accurately understand how we're growing and what we can do to build the software into everything that it can possibly be. The telemetry that we collect also help us demonstrate our growth in an accurate manner, which helps us as we seek investment to build and scale our team. If we can accurately demonstrate our growth, we can more effectively continue to support Payload as free and open-source software. To opt out of telemetry, you can pass `telemetry: false` within your Payload config.
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
title: Migrations
|
||||
label: Migrations
|
||||
order: 20
|
||||
keywords: database, migrations, ddl, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
|
||||
keywords: database, migrations, ddl, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
|
||||
desc: Payload features first-party database migrations all done in TypeScript.
|
||||
---
|
||||
|
||||
Payload exposes a full suite of migration controls available for your use. Migration commands are accessible via the `npm run payload` command in your project directory.
|
||||
Payload exposes a full suite of migration controls available for your use. Migration commands are accessible via
|
||||
the `npm run payload` command in your project directory.
|
||||
|
||||
Ensure you have an npm script called "payload" in your `package.json` file.
|
||||
|
||||
@@ -19,38 +20,48 @@ Ensure you have an npm script called "payload" in your `package.json` file.
|
||||
```
|
||||
|
||||
<Banner>
|
||||
Note that you need to run Payload migrations through the package manager that you are using, because Payload should not be globally installed on your system.
|
||||
Note that you need to run Payload migrations through the package manager that you are using,
|
||||
because Payload should not be globally installed on your system.
|
||||
</Banner>
|
||||
|
||||
### Migration file contents
|
||||
## Migration file contents
|
||||
|
||||
Payload stores all created migrations in a folder that you can specify. By default, migrations are stored in `./src/migrations`.
|
||||
Payload stores all created migrations in a folder that you can specify. By default, migrations are stored
|
||||
in `./src/migrations`.
|
||||
|
||||
A migration file has two exports - an `up` function, which is called when a migration is executed, and a `down` function that will be called if for some reason the migration fails to complete successfully. The `up` function should contain all changes that you attempt to make within the migration, and the `down` should ideally revert any changes you make.
|
||||
A migration file has two exports - an `up` function, which is called when a migration is executed, and a `down` function
|
||||
that will be called if for some reason the migration fails to complete successfully. The `up` function should contain
|
||||
all changes that you attempt to make within the migration, and the `down` should ideally revert any changes you make.
|
||||
|
||||
For an added level of safety, migrations should leverage Payload [transactions](/docs/database/transactions).
|
||||
For an added level of safety, migrations should leverage Payload [transactions](/docs/database/transactions). Migration
|
||||
functions should make use of the `req` by adding it to the arguments of your payload local API calls such
|
||||
as `payload.create` and database adapter methods like `payload.db.create`.
|
||||
|
||||
Here is an example migration file:
|
||||
|
||||
```ts
|
||||
import { MigrateUpArgs, MigrateDownArgs } from '@payloadcms/your-db-adapter'
|
||||
|
||||
export async function up({ payload }: MigrateUpArgs): Promise<void> {
|
||||
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
|
||||
// Perform changes to your database here.
|
||||
// You have access to `payload` as an argument, and
|
||||
// everything is done in TypeScript.
|
||||
};
|
||||
}
|
||||
|
||||
export async function down({ payload }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
|
||||
// Do whatever you need to revert changes if the `up` function fails
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Migrations Directory
|
||||
## Migrations Directory
|
||||
|
||||
Each DB adapter has an optional property `migrationDir` where you can override where you want your migrations to be stored/read. If this is not specified, Payload will check the default and possibly make a best effort to find your migrations directory by searching in common locations ie. `./src/migrations`, `./dist/migrations`, `./migrations`, etc.
|
||||
Each DB adapter has an optional property `migrationDir` where you can override where you want your migrations to be
|
||||
stored/read. If this is not specified, Payload will check the default and possibly make a best effort to find your
|
||||
migrations directory by searching in common locations ie. `./src/migrations`, `./dist/migrations`, `./migrations`, etc.
|
||||
|
||||
All database adapters should implement similar migration patterns, but there will be small differences based on the adapter and its specific needs. Below is a list of all migration commands that should be supported by your database adapter.
|
||||
All database adapters should implement similar migration patterns, but there will be small differences based on the
|
||||
adapter and its specific needs. Below is a list of all migration commands that should be supported by your database
|
||||
adapter.
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -64,7 +75,8 @@ npm run payload migrate
|
||||
|
||||
### Create
|
||||
|
||||
Create a new migration file in the migrations directory. You can optionally name the migration that will be created. By default, migrations will be named using a timestamp.
|
||||
Create a new migration file in the migrations directory. You can optionally name the migration that will be created. By
|
||||
default, migrations will be named using a timestamp.
|
||||
|
||||
```text
|
||||
npm run payload migrate:create optional-name-here
|
||||
@@ -72,7 +84,8 @@ npm run payload migrate:create optional-name-here
|
||||
|
||||
### Status
|
||||
|
||||
The `migrate:status` command will check the status of migrations and output a table of which migrations have been run, and which migrations have not yet run.
|
||||
The `migrate:status` command will check the status of migrations and output a table of which migrations have been run,
|
||||
and which migrations have not yet run.
|
||||
|
||||
`payload migrate:status`
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@ title: MongoDB
|
||||
label: MongoDB
|
||||
order: 40
|
||||
desc: Payload has supported MongoDB natively since we started. The flexible nature of MongoDB lends itself well to Payload's powerful fields.
|
||||
keywords: MongoDB, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: MongoDB, documentation, typescript, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to store your Payload data in MongoDB.
|
||||
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to
|
||||
store your Payload data in MongoDB.
|
||||
|
||||
Then from there, pass it to your Payload config as follows:
|
||||
|
||||
@@ -27,18 +28,20 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
### Options
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `autoPluralization` | Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
|
||||
| `connectOptions` | Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
|
||||
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| Option | Description |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
|
||||
| `autoPluralization` | Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
|
||||
| `connectOptions` | Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
|
||||
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| `transactionOptions` | An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. | |
|
||||
|
||||
### Access to Mongoose models
|
||||
## Access to Mongoose models
|
||||
|
||||
After Payload is initialized, this adapter exposes all of your Mongoose models and they are available for you to work with directly.
|
||||
After Payload is initialized, this adapter exposes all of your Mongoose models and they are available for you to work
|
||||
with directly.
|
||||
|
||||
You can access Mongoose models as follows:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Database
|
||||
label: Overview
|
||||
order: 10
|
||||
keywords: database, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
|
||||
keywords: database, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
|
||||
desc: With Payload, you bring your own database and own your data. You have full control.
|
||||
---
|
||||
|
||||
@@ -19,7 +19,7 @@ To use a specific database adapter, you need to install it and configure it acco
|
||||
|
||||
There are several factors to consider when choosing which database technology and hosting option is right for your project and workload. Payload can theoretically support any database, but it's up to you to decide which database to use.
|
||||
|
||||
#### When to use MongoDB
|
||||
### When to use MongoDB
|
||||
|
||||
If your project has a lot of dynamic fields, and you are comfortable with allowing Payload to enforce data integrity across your documents, MongoDB is a great choice. With it, your Payload documents are stored as _one_ document in your database—no matter if you have localization enabled, how many block or array fields you have, etc. This means that the shape of your data in your database will very closely reflect your field schema, and there is minimal complexity involved in storing or retrieving your data.
|
||||
|
||||
@@ -30,7 +30,7 @@ You should prefer MongoDB if:
|
||||
- Most (or everything) in your project is localized
|
||||
- You leverage a lot of array fields, block fields, or `hasMany` select fields and similar
|
||||
|
||||
#### When to use a relational DB
|
||||
### When to use a relational DB
|
||||
|
||||
Many projects might call for more rigid database architecture where the shape of your data is strongly enforced at the database level. For example, if you know the shape of your data and it's relatively "flat", and you don't anticipate it to change often, your workload might suit relational databases like Postgres very well.
|
||||
|
||||
@@ -40,17 +40,17 @@ You should prefer a relational DB like Postgres if:
|
||||
- You require enforced data consistency at the database level
|
||||
- You have a lot of relationships between collections and require relationships to be enforced
|
||||
|
||||
#### Differences in Payload features
|
||||
### Differences in Payload features
|
||||
|
||||
It's important to note that almost everything Payload does is available in all of our officially supported database adapters, including localization, arrays, blocks, etc.
|
||||
It's important to note that almost everything Payload does is available in all of our officially supported database adapters, including localization, arrays, blocks, etc.
|
||||
|
||||
The only thing that is not supported in Postgres yet is the [Point field](/docs/fields/point), but that should be added soon.
|
||||
The only thing that is not supported in Postgres yet is the [Point field](/docs/fields/point), but that should be added soon.
|
||||
|
||||
It's up to you to choose which database you would like to use.
|
||||
|
||||
## Configuration
|
||||
|
||||
To configure the database for your Payload application, an adapter can be assigned to `config.db`. This property is required within your Payload config.
|
||||
To configure the database for your Payload application, an adapter can be assigned to `config.db`. This property is required within your Payload config.
|
||||
|
||||
Here's an example:
|
||||
|
||||
@@ -67,7 +67,7 @@ export default buildConfig({
|
||||
db: postgresAdapter({
|
||||
pool: {
|
||||
connectionString: process.env.DATABASE_URI,
|
||||
}
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
title: Postgres
|
||||
label: Postgres
|
||||
order: 50
|
||||
desc: Payload supports Postgres through an officially supported Drizzle database adapter.
|
||||
keywords: Postgres, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
|
||||
desc: Payload supports Postgres through an officially supported Drizzle database adapter.
|
||||
keywords: Postgres, documentation, typescript, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.
|
||||
|
||||
<Banner>
|
||||
The Postgres database adapter is currently in beta. If you would like to help us test this package, we'd love to hear if you find any bugs or issues!
|
||||
The Postgres database adapter is currently in beta. If you would like to help us test this
|
||||
package, we'd love to hear if you find any bugs or issues!
|
||||
</Banner>
|
||||
|
||||
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
|
||||
@@ -30,20 +31,27 @@ export default buildConfig({
|
||||
// `pool` is required.
|
||||
pool: {
|
||||
connectionString: process.env.DATABASE_URI,
|
||||
}
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
### Options
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `pool` | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
|
||||
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| Option | Description |
|
||||
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `pool` \* | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
|
||||
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
|
||||
| `schemaName` | A string for the postgres schema to use, defaults to 'public'. |
|
||||
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '_locales'. |
|
||||
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '_rels'. |
|
||||
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '_v'. |
|
||||
|
||||
### Access to Drizzle
|
||||
|
||||
|
||||
## Access to Drizzle
|
||||
|
||||
After Payload is initialized, this adapter will expose the full power of Drizzle to you for use if you need it.
|
||||
|
||||
@@ -53,7 +61,7 @@ You can access Drizzle as follows:
|
||||
payload.db.drizzle
|
||||
```
|
||||
|
||||
### Tables, relations, and enums
|
||||
## Tables, relations, and enums
|
||||
|
||||
In addition to exposing Drizzle directly, all of the tables, Drizzle relations, and enum configs are exposed for you via the `payload.db` property as well.
|
||||
|
||||
@@ -61,27 +69,29 @@ In addition to exposing Drizzle directly, all of the tables, Drizzle relations,
|
||||
- Enums - `payload.db.enums`
|
||||
- Relations - `payload.db.relations`
|
||||
|
||||
### Prototyping in development mode
|
||||
## Prototyping in development mode
|
||||
|
||||
Drizzle exposes two ways to work locally in development mode.
|
||||
|
||||
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload config. This only works in development mode, and should not be mixed with manually running [`migrate`](/docs/database/migrations) commands.
|
||||
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload config. This only works in development mode, and should not be mixed with manually running [`migrate`](/docs/database/migrations) commands.
|
||||
|
||||
You will be warned if any changes that you make will entail data loss while in development mode. Push is enabled by default, but you can opt out if you'd like.
|
||||
|
||||
Alternatively, you can disable `push` and rely solely on migrations to keep your local database in sync with your Payload config.
|
||||
|
||||
### Migration workflows
|
||||
## Migration workflows
|
||||
|
||||
Migrations are extremely powerful thanks to the seamless way that Payload and Drizzle work together. Let's take the following scenario:
|
||||
|
||||
1. You are building your Payload config locally, with a local database used for testing.
|
||||
1. You have left the default setting of `push` enabled, so every time you change your Payload config (add or remove fields, collections, etc.), Drizzle will automatically push changes to your local DB.
|
||||
1. Once you're done with your changes, or have completed a feature, you can run `npm run payload migrate:create`.
|
||||
1. Once you're done with your changes, or have completed a feature, you can run `npm run payload migrate:create`.
|
||||
1. Payload and Drizzle will look for any existing migrations, and automatically generate all SQL changes necessary to convert your schema from its prior state into the state of your current Payload config, and store the resulting DDL in a newly created migration.
|
||||
1. Once you're ready to go to production, you will be able to run `npm run payload migrate` against your production database, which will apply any new migrations that have not yet run.
|
||||
1. Now your production database is in sync with your Payload config!
|
||||
|
||||
<Banner type="warning">
|
||||
Warning: do not mix "push" and migrations with your local development database. If you use "push" locally, and then try to migrate, Payload will throw a warning, telling you that these two methods are not meant to be used interchangeably.
|
||||
</Banner>
|
||||
Warning: do not mix "push" and migrations with your local development database. If you use "push"
|
||||
locally, and then try to migrate, Payload will throw a warning, telling you that these two methods
|
||||
are not meant to be used interchangeably.
|
||||
</Banner>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Transactions
|
||||
label: Transactions
|
||||
order: 30
|
||||
keywords: database, transactions, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
|
||||
keywords: database, transactions, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
|
||||
desc: Database transactions are fully supported within Payload.
|
||||
---
|
||||
|
||||
@@ -20,7 +20,8 @@ The initial request made to Payload will begin a new transaction and attach it t
|
||||
|
||||
```ts
|
||||
const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
// because req.transactionID is assigned from Payload and passed through, my-slug will only persist if the entire request is successful
|
||||
// because req.transactionID is assigned from Payload and passed through,
|
||||
// my-slug will only persist if the entire request is successful
|
||||
await req.payload.create({
|
||||
req,
|
||||
collection: 'my-slug',
|
||||
@@ -31,7 +32,7 @@ const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
}
|
||||
```
|
||||
|
||||
### Async Hooks with Transactions
|
||||
## Async Hooks with Transactions
|
||||
|
||||
Since Payload hooks can be async and be written to not await the result, it is possible to have an incorrect success response returned on a request that is rolled back. If you have a hook where you do not `await` the result, then you should **not** pass the `req.transactionID`.
|
||||
|
||||
@@ -48,7 +49,7 @@ const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
})
|
||||
|
||||
// Should this call fail, it will not rollback other changes
|
||||
// because the req (and its transationID) is not passed through
|
||||
// because the req (and its transactionID) is not passed through
|
||||
const safelyIgnoredAsync = req.payload.create({
|
||||
collection: 'my-slug',
|
||||
data: {
|
||||
@@ -58,7 +59,7 @@ const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
}
|
||||
```
|
||||
|
||||
### Direct Transaction Access
|
||||
## Direct Transaction Access
|
||||
|
||||
When writing your own scripts or custom endpoints, you may wish to have direct control over transactions. This is useful for interacting with your database outside of Payload's local API.
|
||||
|
||||
@@ -66,4 +67,4 @@ The following functions can be used for managing transactions:
|
||||
|
||||
`payload.db.beginTransaction` - Starts a new session and returns a transaction ID for use in other Payload Local API calls.
|
||||
`payload.db.commitTransaction` - Takes the identifier for the transaction, finalizes any changes.
|
||||
`payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
|
||||
`payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
|
||||
|
||||
@@ -2,169 +2,165 @@
|
||||
title: Email Functionality
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Payload uses NodeMailer to allow you to send emails smoothly from your app. Set up email functions such as password resets, order confirmations and more.
|
||||
keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
desc: Payload uses an adapter pattern to enable email functionality. Set up email functions such as password resets, order confirmations and more.
|
||||
keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
### Introduction
|
||||
## Introduction
|
||||
|
||||
Payload comes ready to send your application's email. Whether you simply need built-in password reset
|
||||
email to work or you want customers to get an order confirmation email, you're almost there. Payload makes use of
|
||||
[NodeMailer](https://nodemailer.com) for email and won't get in your way for those already familiar.
|
||||
Payload has a few email adapters that can be imported to enable email functionality. The [@payloadcms/email-nodemailer](https://www.npmjs.com/package/@payloadcms/email-nodemailer) package will be the package most will want to install. This package provides an easy way to use [Nodemailer](https://nodemailer.com) for email and won't get in your way for those already familiar.
|
||||
|
||||
For email to send from your Payload server, some configuration is required. The settings you provide will be set
|
||||
in the `email` property object of your payload init call. Payload will make use of the transport that you have configured for it for things like reset password or verifying new user accounts and email send methods are available to you as well on your payload instance.
|
||||
The email adapter should be passed into the `email` property of the Payload config. This will allow Payload to send emails for things like password resets, new user verification, and any other email sending needs you may have.
|
||||
|
||||
### Configuration
|
||||
## Configuration
|
||||
|
||||
**Three ways to set it up**
|
||||
### Default Configuration
|
||||
|
||||
1. **Default**: When email is not needed, a mock email handler will be created and used when nothing is provided. This is ideal for development environments and can be changed later when ready to [go to production](/docs/production/deployment).
|
||||
1. **Recommended**: Set the `transportOptions` and Payload will do the set up for you.
|
||||
1. **Advanced**: The `transport` object can be assigned a nodemailer transport object set up in your server scripts and given for Payload to use.
|
||||
When email is not needed or desired, Payload will log a warning on startup notifying that email is not configured. A warning message will also be logged on any attempt to send an email.
|
||||
|
||||
The following options are configurable in the `email` property object as part of the options object when calling payload.init().
|
||||
### Email Adapter
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`fromName`** \* | The name part of the From field that will be seen on the delivered email |
|
||||
| **`fromAddress`** \* | The email address part of the From field that will be used when delivering email |
|
||||
| **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set |
|
||||
| **`transportOptions`** | An object that configures the transporter that Payload will create. For all the available options see the [NodeMailer documentation](https://nodemailer.com/smtp/) or see the examples below |
|
||||
| **`logMockCredentials`** | If set to true and no transport/transportOptions, ethereal credentials will be logged to console on startup |
|
||||
An email adapter will require at least the following fields:
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
| Option | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------- |
|
||||
| **`defaultFromName`** \* | The name part of the From field that will be seen on the delivered email |
|
||||
| **`defaultFromAddress`** \* | The email address part of the From field that will be used when delivering email |
|
||||
|
||||
### Use SMTP
|
||||
|
||||
Simple Mail Transfer Protocol, also known as SMTP can be passed in using the `transportOptions` object on the `email` options.
|
||||
### Official Email Adapters
|
||||
|
||||
**Example email part using SMTP:**
|
||||
| Name | Package | Description |
|
||||
| ---------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Nodemailer | [@payloadcms/email-nodemailer](https://www.npmjs.com/package/@payloadcms/email-nodemailer) | Use any [Nodemailer transport](https://nodemailer.com/transports), including SMTP, Resend, SendGrid, and more. This was provided by default in Payload 2.x. This is the easiest migration path. |
|
||||
| Resend | [@payloadcms/email-resend](https://www.npmjs.com/package/@payloadcms/email-resend) | Resend email via their REST API. This is preferred for serverless platforms such as Vercel because it is much more lightweight than the nodemailer adapter. |
|
||||
|
||||
## Nodemailer Configuration
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`transport`** | The Nodemailer transport object for when you want to do it yourself, not needed when transportOptions is set |
|
||||
| **`transportOptions`** | An object that configures the transporter that Payload will create. For all the available options see the [Nodemailer documentation](https://nodemailer.com) or see the examples below |
|
||||
|
||||
## Use SMTP
|
||||
|
||||
Simple Mail Transfer Protocol (SMTP) options can be passed in using the `transportOptions` object on the `email` options. See the [Nodemailer SMTP documentation](https://nodemailer.com/smtp/) for more information, including details on when `secure` should and should not be set to `true`.
|
||||
|
||||
**Example email options using SMTP:**
|
||||
|
||||
```ts
|
||||
payload.init({
|
||||
email: {
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
|
||||
|
||||
export default buildConfig({
|
||||
email: nodemailerAdapter({
|
||||
defaultFromAddress: 'info@payloadcms.com',
|
||||
defaultFromName: 'Payload',
|
||||
// Nodemailer transportOptions
|
||||
transportOptions: {
|
||||
host: process.env.SMTP_HOST,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
port: 587,
|
||||
secure: true, // use TLS
|
||||
tls: {
|
||||
// do not fail on invalid certs
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
},
|
||||
fromName: 'hello',
|
||||
fromAddress: 'hello@example.com',
|
||||
},
|
||||
// ...
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
<Banner type="warning">
|
||||
It is best practice to avoid saving credentials or API keys directly in your code, use
|
||||
[environment variables](/docs/configuration/overview#using-environment-variables-in-your-config).
|
||||
</Banner>
|
||||
|
||||
### Use an email service
|
||||
|
||||
Many third party mail providers are available and offer benefits beyond basic SMTP. As an example your payload init could look this if you wanted to use SendGrid.com though the same approach would work for any other [NodeMailer transports](https://nodemailer.com/transports/) shown here or provided by another third party.
|
||||
**Example email options using nodemailer.createTransport:**
|
||||
|
||||
```ts
|
||||
import payload from 'payload'
|
||||
import nodemailerSendgrid from 'nodemailer-sendgrid'
|
||||
|
||||
const sendGridAPIKey = process.env.SENDGRID_API_KEY
|
||||
|
||||
payload.init({
|
||||
...(sendGridAPIKey
|
||||
? {
|
||||
email: {
|
||||
transportOptions: nodemailerSendgrid({
|
||||
apiKey: sendGridAPIKey,
|
||||
}),
|
||||
fromName: 'Admin',
|
||||
fromAddress: 'admin@example.com',
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
```
|
||||
|
||||
### Use a custom NodeMailer transport
|
||||
|
||||
To take full control of the mail transport you may wish to use `nodemailer.createTransport()` on your server and provide it to Payload init.
|
||||
|
||||
```ts
|
||||
import payload from 'payload'
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
|
||||
import nodemailer from 'nodemailer'
|
||||
|
||||
const payload = require('payload')
|
||||
const nodemailer = require('nodemailer')
|
||||
|
||||
const transport = await nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
})
|
||||
|
||||
payload.init({
|
||||
email: {
|
||||
fromName: 'Admin',
|
||||
fromAddress: 'admin@example.com',
|
||||
transport,
|
||||
},
|
||||
// ...
|
||||
export default buildConfig({
|
||||
email: nodemailerAdapter({
|
||||
defaultFromAddress: 'info@payloadcms.com',
|
||||
defaultFromName: 'Payload',
|
||||
// Any Nodemailer transport can be used
|
||||
transport: nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
### Sending Mail
|
||||
**Custom Transport:**
|
||||
|
||||
With a working transport you can call it anywhere you have access to payload by calling `payload.sendEmail(message)`. The `message` will contain the `to`, `subject` and `email` or `text` for the email being sent. To see all available message configuration options see [NodeMailer](https://nodemailer.com/message).
|
||||
You also have the ability to bring your own nodemailer transport. This is an example of using the SendGrid nodemailer transport.
|
||||
|
||||
### Mock transport
|
||||
|
||||
By default, Payload uses a mock implementation that only sends mail to the [ethereal](https://ethereal.email) capture service that will never reach a user's inbox. While in development you may wish to make use of the captured messages which is why the payload output during server output helpfully logs this out on the server console.
|
||||
|
||||
To see ethereal credentials, add `logMockCredentials: true` to the email options. This will cause them to be logged to console on startup.
|
||||
|
||||
```ts
|
||||
payload.init({
|
||||
email: {
|
||||
fromName: 'Admin',
|
||||
fromAddress: 'admin@example.com',
|
||||
logMockCredentials: true, // Optional
|
||||
},
|
||||
// ...
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
|
||||
import nodemailerSendgrid from 'nodemailer-sendgrid'
|
||||
|
||||
|
||||
export default buildConfig({
|
||||
email: nodemailerAdapter({
|
||||
defaultFromAddress: 'info@payloadcms.com',
|
||||
defaultFromName: 'Payload',
|
||||
transportOptions: nodemailerSendgrid({
|
||||
apiKey: process.env.SENDGRID_API_KEY,
|
||||
}),
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
**Console output when starting payload with a mock email instance and logMockCredentials: true**
|
||||
During development, if you pass nothing to `nodemailerAdapter`, it will use the [ethereal.email](https://ethereal.email) service.
|
||||
|
||||
```
|
||||
[06:37:21] INFO (payload): Starting Payload...
|
||||
[06:37:22] INFO (payload): Payload Demo Initialized
|
||||
[06:37:22] INFO (payload): listening on 3000...
|
||||
[06:37:22] INFO (payload): Connected to MongoDB server successfully!
|
||||
[06:37:23] INFO (payload): E-mail configured with mock configuration
|
||||
[06:37:23] INFO (payload): Log into mock email provider at https://ethereal.email
|
||||
[06:37:23] INFO (payload): Mock email account username: hhav5jw7doo4euev@ethereal.email
|
||||
[06:37:23] INFO (payload): Mock email account password: VNdGcvDZeyEhtuPBqf
|
||||
This will log the ethereal.email details to console on startup.
|
||||
|
||||
```ts
|
||||
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
|
||||
|
||||
export default buildConfig({
|
||||
email: nodemailerAdapter(),
|
||||
})
|
||||
```
|
||||
|
||||
The mock email handler is used when payload is started with neither `transport` or `transportOptions` to know how to deliver email.
|
||||
## Resend Configuration
|
||||
|
||||
<Banner type="warning">
|
||||
The randomly generated email account username and password will be different each time the Payload
|
||||
server starts.
|
||||
</Banner>
|
||||
The Resend adapter requires an API key to be passed in the options. This can be found in the Resend dashboard. This is the preferred package if you are deploying on Vercel because this is much more lightweight than the Nodemailer adapter.
|
||||
|
||||
### Using multiple mail providers
|
||||
| Option | Description |
|
||||
| ------ | ----------------------------------- |
|
||||
| apiKey | The API key for the Resend service. |
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { resendAdapter } from '@payloadcms/email-resend'
|
||||
|
||||
export default buildConfig({
|
||||
email: resendAdapter({
|
||||
defaultFromAddress: 'dev@payloadcms.com',
|
||||
defaultFromName: 'Payload CMS',
|
||||
apiKey: process.env.RESEND_API_KEY || '',
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
## Sending Mail
|
||||
|
||||
With a working transport you can call it anywhere you have access to payload by calling `payload.sendEmail(message)`. The `message` will contain the `to`, `subject` and `html` or `text` for the email being sent. Other options are also available and can be seen in the sendEmail args. Support for these will depend on the adapter being used.
|
||||
|
||||
```ts
|
||||
// Example of sending an email
|
||||
const email = await payload.sendEmail({
|
||||
to: 'test@example.com',
|
||||
subject: 'This is a test email',
|
||||
text: 'This is my message body',
|
||||
})
|
||||
```
|
||||
|
||||
## Using multiple mail providers
|
||||
|
||||
Payload supports the use of a single transporter of email, but there is nothing stopping you from having more. Consider a use case where sending bulk email is handled differently than transactional email and could be done using a [hook](/docs/hooks/overview).
|
||||
|
||||
40
docs/examples/overview.mdx
Normal file
40
docs/examples/overview.mdx
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Examples
|
||||
label: Overview
|
||||
order: 10
|
||||
desc:
|
||||
keywords: example, examples, starter, boilerplate, template, templates
|
||||
---
|
||||
|
||||
Payload provides a vast array of examples to help you get started with your project no matter what you are working on. These examples are designed to be easy to get up and running, and to be easy to understand. They showcase nothing more than the specific features being demonstrated so you can easily decipher what is going on.
|
||||
|
||||
Examples are changing every day, so be sure to check back often to see what new examples have been added. If you have a specific example you would like to see, please feel free to start a new [Discussion](https://github.com/payloadcms/payload/discussions) or open a new [PR](https://github.com/payloadcms/payload/pulls) to add it yourself.
|
||||
|
||||
- [Auth](https://github.com/payloadcms/payload/tree/main/examples/auth)
|
||||
- [Custom Server](https://github.com/payloadcms/payload/tree/main/examples/custom-server)
|
||||
- [Draft Preview](https://github.com/payloadcms/payload/tree/main/examples/draft-preview)
|
||||
- [Email](https://github.com/payloadcms/payload/tree/main/examples/email)
|
||||
- [Form Builder](https://github.com/payloadcms/payload/tree/main/examples/form-builder)
|
||||
- [Hierarchy](https://github.com/payloadcms/payload/tree/main/examples/hierarchy)
|
||||
- [Live Preview](https://github.com/payloadcms/payload/tree/main/examples/live-preview)
|
||||
- [Multi-tenant](https://github.com/payloadcms/payload/tree/main/examples/multi-tenant)
|
||||
- [Nested Docs](https://github.com/payloadcms/payload/tree/main/examples/nested-docs)
|
||||
- [Redirects](https://github.com/payloadcms/payload/tree/main/examples/redirects)
|
||||
- [Tailwind / Shadcn-ui](https://github.com/payloadcms/payload/tree/main/examples/tailwind-shadcn-ui)
|
||||
- [Tests](https://github.com/payloadcms/payload/tree/main/examples/testing)
|
||||
- [Virtual Fields](https://github.com/payloadcms/payload/tree/main/examples/virtual-fields)
|
||||
- [White-label Admin UI](https://github.com/payloadcms/payload/tree/main/examples/whitelabel)
|
||||
|
||||
When necessary, some examples include a front-end. Examples that require a front-end share this folder structure:
|
||||
|
||||
```plaintext
|
||||
example/
|
||||
├── payload/
|
||||
├── next-app/
|
||||
├── next-pages/
|
||||
├── react-router/
|
||||
├── vue/
|
||||
├── svelte/
|
||||
```
|
||||
|
||||
...where `payload` is your Payload project, and the other directories are dedicated to their respective front-end framework. We are adding new examples every day, so if your framework of choice is not yet supported in any particular example, please feel free to start a new [Discussion](https://github.com/payloadcms/payload/discussions) or open a new [PR](https://github.com/payloadcms/payload/pulls) to add it yourself.
|
||||
@@ -3,7 +3,7 @@ title: Array Field
|
||||
label: Array
|
||||
order: 20
|
||||
desc: Array fields are intended for sets of repeating fields, that you define. Learn how to use array fields, see examples and options.
|
||||
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -24,7 +24,7 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
|
||||
- Navigational structures where editors can specify nav items containing pages ([relationship field](/docs/fields/relationship)), an "open in new tab" [checkbox field](/docs/fields/checkbox)
|
||||
- Event agenda "timeslots" where you need to specify start & end time ([date field](/docs/fields/date)), label ([text field](/docs/fields/text)), and Learn More page [relationship](/docs/fields/relationship)
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -45,10 +45,11 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`dbName`** | Custom table name for the field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
@@ -56,8 +57,9 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
|
||||
| ------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`initCollapsed`** | Set the initial collapsed state |
|
||||
| **`components.RowLabel`** | Function or React component to be rendered as the label on the array row. Receives `({ data, index, path })` as args |
|
||||
| **`isSortable`** | Disable order sorting by setting this value to `false` |
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Blocks Field
|
||||
label: Blocks
|
||||
order: 30
|
||||
desc: The Blocks field type is a great layout build and can be used to construct any flexible content model. Learn how to use Block fields, see examples and options.
|
||||
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -26,7 +26,7 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
|
||||
- A form builder tool where available block configs might be `Text`, `Select`, or `Checkbox`.
|
||||
- Virtual event agenda "timeslots" where a timeslot could either be a `Break`, a `Presentation`, or a `BreakoutSession`.
|
||||
|
||||
### Field config
|
||||
## Field config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -49,15 +49,16 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ------------------------------- |
|
||||
| **`initCollapsed`** | Set the initial collapsed state |
|
||||
| Option | Description |
|
||||
| ------------------- | ---------------------------------- |
|
||||
| **`initCollapsed`** | Set the initial collapsed state |
|
||||
| **`isSortable`** | Disable order sorting by setting this value to `false` |
|
||||
|
||||
### Block configs
|
||||
## Block configs
|
||||
|
||||
Blocks are defined as separate configs of their own.
|
||||
|
||||
@@ -80,8 +81,10 @@ Blocks are defined as separate configs of their own.
|
||||
| **`imageAltText`** | Customize this block's image thumbnail alt text. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`graphQL.singularName`** | Text to use for the GraphQL schema name. Auto-generated from slug if not defined. NOTE: this is set for deprecation, prefer `interfaceName`. |
|
||||
| **`dbName`** | Custom table name for this block type when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from slug if not defined.
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
#### Auto-generated data per block
|
||||
### Auto-generated data per block
|
||||
|
||||
In addition to the field data that you define on each block, Payload will store two additional properties on each block:
|
||||
|
||||
@@ -93,7 +96,7 @@ The `blockType` is saved as the slug of the block that has been selected.
|
||||
|
||||
The Admin panel provides each block with a `blockName` field which optionally allows editors to label their blocks for better editability and readability.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.js`
|
||||
|
||||
@@ -136,7 +139,7 @@ export const ExampleCollection: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
## TypeScript
|
||||
|
||||
As you build your own Block configs, you might want to store them in separate files but retain typing accordingly. To do so, you can import and use Payload's `Block` type:
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Checkbox Field
|
||||
label: Checkbox
|
||||
order: 40
|
||||
desc: Checkbox field types allow the developer to save a boolean value in the database. Learn how to use Checkbox fields, see examples and options.
|
||||
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>The Checkbox field type saves a boolean in the database.</Banner>
|
||||
@@ -15,27 +15,27 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
|
||||
caption="Admin panel screenshot of Checkbox field with Text field below"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ label: Code
|
||||
order: 50
|
||||
desc: The Code field type will store any string in the Database. Learn how to use Code fields, see examples and options.
|
||||
|
||||
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -21,30 +21,30 @@ keywords: code, fields, config, configuration, documentation, Content Management
|
||||
|
||||
This field uses the `monaco-react` editor syntax highlighting.
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database#overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
@@ -53,7 +53,7 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
|
||||
| **`language`** | This property can be set to any language listed [here](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages). |
|
||||
| **`editorOptions`** | Options that can be passed to the monaco editor, [view the full list](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IDiffEditorConstructionOptions.html). |
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Collapsible Field
|
||||
label: Collapsible
|
||||
order: 60
|
||||
desc: With the Collapsible field, you can place fields within a collapsible layout component that can be collapsed / expanded.
|
||||
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,7 +18,7 @@ keywords: row, fields, config, configuration, documentation, Content Management
|
||||
caption="Admin panel screenshot of a Collapsible field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -29,7 +29,7 @@ keywords: row, fields, config, configuration, documentation, Content Management
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
@@ -37,7 +37,7 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
|
||||
| ------------------- | ------------------------------- |
|
||||
| **`initCollapsed`** | Set the initial collapsed state |
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Date Field
|
||||
label: Date
|
||||
order: 70
|
||||
desc: The Date field type stores a Date in the database. Learn how to use and customize the Date field, see examples and options.
|
||||
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -20,48 +20,48 @@ keywords: date, fields, config, configuration, documentation, Content Management
|
||||
|
||||
This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepicker) for the Admin panel component.
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can customize the following fields that will adjust how the component displays in the admin panel via the `date` property.
|
||||
|
||||
| Property | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| **`placeholder`** | Placeholder text for the field. |
|
||||
| **`date`** | Pass options to customize date field appearance. |
|
||||
| **`date.displayFormat`** | Format date to be shown in field **cell**. |
|
||||
| **`date.pickerAppearance`** \* | Determines the appearance of the datepicker: `dayAndTime` `timeOnly` `dayOnly` `monthOnly`. |
|
||||
| **`date.monthsToShow`** \* | Number of months to display max is 2. Defaults to 1. |
|
||||
| **`date.minDate`** \* | Min date value to allow. |
|
||||
| **`date.maxDate`** \* | Max date value to allow. |
|
||||
| **`date.minTime`** \* | Min time value to allow. |
|
||||
| **`date.maxTime`** \* | Max date value to allow. |
|
||||
| **`date.overrides`** \* | Pass any valid props directly to the [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md) |
|
||||
| **`date.timeIntervals`** \* | Time intervals to display. Defaults to 30 minutes. |
|
||||
| **`date.timeFormat`** \* | Determines time format. Defaults to `'h:mm aa'`. |
|
||||
| Property | Description |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`placeholder`** | Placeholder text for the field. |
|
||||
| **`date`** | Pass options to customize date field appearance. |
|
||||
| **`date.displayFormat`** | Format date to be shown in field **cell**. |
|
||||
| **`date.pickerAppearance`** \* | Determines the appearance of the datepicker: `dayAndTime` `timeOnly` `dayOnly` `monthOnly`. |
|
||||
| **`date.monthsToShow`** \* | Number of months to display max is 2. Defaults to 1. |
|
||||
| **`date.minDate`** \* | Min date value to allow. |
|
||||
| **`date.maxDate`** \* | Max date value to allow. |
|
||||
| **`date.minTime`** \* | Min time value to allow. |
|
||||
| **`date.maxTime`** \* | Max date value to allow. |
|
||||
| **`date.overrides`** \* | Pass any valid props directly to the [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md) |
|
||||
| **`date.timeIntervals`** \* | Time intervals to display. Defaults to 30 minutes. |
|
||||
| **`date.timeFormat`** \* | Determines time format. Defaults to `'h:mm aa'`. |
|
||||
|
||||
_\* This property is passed directly to [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md). ._
|
||||
|
||||
#### Display Format and Picker Appearance
|
||||
### Display Format and Picker Appearance
|
||||
|
||||
These properties only affect how the date is displayed in the UI. The full date is always stored in the format `YYYY-MM-DDTHH:mm:ss.SSSZ` (e.g. `1999-01-01T8:00:00.000+05:00`).
|
||||
|
||||
@@ -71,7 +71,7 @@ These properties only affect how the date is displayed in the UI. The full date
|
||||
|
||||
When only `pickerAppearance` is set, an equivalent format will be rendered in the date field cell. To overwrite this format, set `displayFormat`.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Email Field
|
||||
label: Email
|
||||
order: 80
|
||||
desc: The Email field enforces that the value provided is a valid email address. Learn how to use Email fields, see examples and options.
|
||||
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>The Email field enforces that the value provided is a valid email address.</Banner>
|
||||
@@ -15,28 +15,28 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
|
||||
caption="Admin panel screenshot of an Email field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), this field type allows for the following `admin` properties:
|
||||
|
||||
@@ -48,7 +48,7 @@ Set this property to define a placeholder string for the field.
|
||||
|
||||
Set this property to a string that will be used for browser autocomplete.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Group Field
|
||||
label: Group
|
||||
order: 90
|
||||
desc: The Group field allows other fields to be nested under a common property. Learn how to use Group fields, see examples and options.
|
||||
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,7 +18,7 @@ keywords: group, fields, config, configuration, documentation, Content Managemen
|
||||
caption="Admin panel screenshot of a Group field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -38,7 +38,7 @@ keywords: group, fields, config, configuration, documentation, Content Managemen
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Group allows for the following admin property:
|
||||
|
||||
@@ -46,7 +46,7 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
|
||||
|
||||
Set this property to `true` to hide this field's gutter within the admin panel. The field gutter is rendered as a vertical line and padding, but often if this field is nested within a Group, Block, or Array, you may want to hide the gutter.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ label: JSON
|
||||
order: 50
|
||||
desc: The JSON field type will store any string in the Database. Learn how to use JSON fields, see examples and options.
|
||||
|
||||
keywords: json, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: json, jsonSchema, schema, validation, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -21,38 +21,39 @@ keywords: json, fields, config, configuration, documentation, Content Management
|
||||
|
||||
This field uses the `monaco-react` editor syntax highlighting.
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`jsonSchema`** | Provide a JSON schema that will be used for validation. [JSON schemas](https://json-schema.org/learn/getting-started-step-by-step)
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin Config
|
||||
## Admin Config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Option | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`editorOptions`** | Options that can be passed to the monaco editor, [view the full list](https://microsoft.github.io/monaco-editor/typedoc/variables/editor.EditorOptions.html). |
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
@@ -68,3 +69,67 @@ export const ExampleCollection: CollectionConfig = {
|
||||
],
|
||||
}
|
||||
```
|
||||
## JSON Schema Validation
|
||||
|
||||
Payload JSON fields fully support the [JSON schema](https://json-schema.org/) standard. By providing a schema in your field config, the editor will be guided in the admin UI, getting typeahead for properties and their formats automatically. When the document is saved, the default validation will prevent saving any invalid data in the field according to the schema in your config.
|
||||
|
||||
If you only provide a URL to a schema, Payload will fetch the desired schema if it is publicly available. If not, it is recommended to add the schema directly to your config or import it from another file so that it can be implemented consistently in your project.
|
||||
|
||||
|
||||
### Local JSON Schema
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
|
||||
export const ExampleCollection: CollectionConfig = {
|
||||
slug: 'example-collection',
|
||||
fields: [
|
||||
{
|
||||
name: 'customerJSON', // required
|
||||
type: 'json', // required
|
||||
jsonSchema: {
|
||||
uri: 'a://b/foo.json', // required
|
||||
fileMatch: ['a://b/foo.json'], // required
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
enum: ['bar', 'foobar'],
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
],
|
||||
}
|
||||
// {"foo": "bar"} or {"foo": "foobar"} - ok
|
||||
// Attempting to create {"foo": "not-bar"} will throw an error
|
||||
```
|
||||
|
||||
### Remote JSON Schema
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
|
||||
export const ExampleCollection: CollectionConfig = {
|
||||
slug: 'example-collection',
|
||||
fields: [
|
||||
{
|
||||
name: 'customerJSON', // required
|
||||
type: 'json', // required
|
||||
jsonSchema: {
|
||||
uri: 'https://example.com/customer.schema.json', // required
|
||||
fileMatch: ['https://example.com/customer.schema.json'], // required
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
// If 'https://example.com/customer.schema.json' has a JSON schema
|
||||
// {"foo": "bar"} or {"foo": "foobar"} - ok
|
||||
// Attempting to create {"foo": "not-bar"} will throw an error
|
||||
```
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Number Field
|
||||
label: Number
|
||||
order: 100
|
||||
desc: Number fields store and validate numeric data. Learn how to use and format Number fields, see examples and Number field options.
|
||||
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,33 +18,33 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
|
||||
caption="Admin panel screenshot of a Number field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), this field type allows for the following `admin` properties:
|
||||
|
||||
@@ -60,7 +60,7 @@ Set this property to define a placeholder string for the field.
|
||||
|
||||
Set this property to a string that will be used for browser autocomplete.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Fields Overview
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Fields are the building blocks of Payload, find out how to add or remove a field, change field type, add hooks, define access control and validation.
|
||||
keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner type="info">
|
||||
@@ -36,7 +36,7 @@ export const Page: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Field types
|
||||
## Field types
|
||||
|
||||
- [Array](/docs/fields/array) - for repeating content, supports nested fields
|
||||
- [Blocks](/docs/fields/blocks) - block-based fields, allowing powerful layout creation
|
||||
@@ -46,6 +46,7 @@ export const Page: CollectionConfig = {
|
||||
- [Date](/docs/fields/date) - date / time field that saves a timestamp
|
||||
- [Email](/docs/fields/email) - validates the entry is a properly formatted email
|
||||
- [Group](/docs/fields/group) - nest fields within an object
|
||||
- [JSON](/docs/fields/json) - saves actual JSON in the database
|
||||
- [Number](/docs/fields/number) - field that enforces that its value be a number
|
||||
- [Point](/docs/fields/point) - geometric coordinates for location data
|
||||
- [Radio](/docs/fields/radio) - radio button group, allowing only one value to be selected
|
||||
@@ -59,19 +60,19 @@ export const Page: CollectionConfig = {
|
||||
- [Upload](/docs/fields/upload) - allows local file and image upload
|
||||
- [UI](/docs/fields/ui) - inject your own custom components and do whatever you need
|
||||
|
||||
### Field-level hooks
|
||||
## Field-level hooks
|
||||
|
||||
One of the most powerful parts about Payload is its ability for you to define field-level hooks that can control the logic of your fields to a fine-grained level. for more information about how to define field hooks, [click here](/docs/hooks/overview#field-hooks).
|
||||
|
||||
### Field-level access control
|
||||
## Field-level access control
|
||||
|
||||
In addition to being able to define access control on a document-level, you can define extremely granular permissions on a field by field level. For more information about field-level access control, [click here](/docs/access-control/overview#fields).
|
||||
|
||||
### Field names
|
||||
## Field names
|
||||
|
||||
Some fields use their `name` property as a unique identifier to store and retrieve from the database. `__v`, `salt`, and `hash` are all reserved field names which are sanitized from Payload's config and cannot be used.
|
||||
|
||||
### Validation
|
||||
## Validation
|
||||
|
||||
Field validation is enforced automatically based on the field type and other properties such as `required` or `min` and `max` value constraints on certain field types. This default behavior can be replaced by providing your own validate function for any field. It will be used on both the frontend and the backend, so it should not rely on any Node-specific packages. The validation function can be either synchronous or asynchronous and expects to return either `true` or a string error message to display in both API responses and within the Admin panel.
|
||||
|
||||
@@ -82,15 +83,15 @@ There are two arguments available to custom validation functions.
|
||||
|
||||
| Property | Description |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `data` | An object of the full collection or global document. |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field. |
|
||||
| `operation` | Will be "create" or "update" depending on the UI action or API call. |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request. |
|
||||
| `t` | The function for translating text, [more](/docs/configuration/i18n). |
|
||||
| `user` | The currently authenticated user object. |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `operation` | Will be `create` or `update` depending on the UI action or API call |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `t` | The function for translating text, [more](/docs/configuration/i18n) |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
| `payload` | If the `validate` function is being executed on the server, Payload will be exposed for easily running local operations. |
|
||||
|
||||
Example:
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
@@ -139,7 +140,7 @@ const field: Field = {
|
||||
}
|
||||
```
|
||||
|
||||
### Customizable ID
|
||||
## Customizable ID
|
||||
|
||||
Collections ID fields are generated automatically by default. An explicit `id` field can be declared in the `fields` array to override this behavior.
|
||||
Users are then required to provide a custom ID value when creating a record through the Admin UI or API.
|
||||
@@ -158,29 +159,31 @@ Example:
|
||||
}
|
||||
```
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to each field's base configuration, you can define specific traits and properties for fields that only have effect on how they are rendered in the Admin panel. The following properties are available for all fields within the `admin` property:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `condition` | You can programmatically show / hide fields based on what other fields are doing. [Click here](#conditional-logic) for more info. |
|
||||
| `components` | All field components can be completely and easily swapped out for custom components that you define. [Click here](#custom-components) for more info. |
|
||||
| `description` | Helper text to display with the field to provide more information for the editor user. [Click here](#description) for more info. |
|
||||
| `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. |
|
||||
| `width` | Restrict the width of a field. you can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a `Row` type where they can be organized horizontally. |
|
||||
| `style` | Attach raw CSS style properties to the root DOM element of a field. |
|
||||
| `className` | Attach a CSS class name to the root DOM element of a field. |
|
||||
| `readOnly` | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. |
|
||||
| `disabled` | If a field is `disabled`, it is completely omitted from the Admin panel. |
|
||||
| `disableBulkEdit` | Set `disableBulkEdit` to `true` to prevent fields from appearing in the select options when making edits for multiple documents. |
|
||||
| `hidden` | Setting a field's `hidden` property on its `admin` config will transform it into a `hidden` input type. Its value will still submit with the Admin panel's requests, but the field itself will not be visible to editors. |
|
||||
| Option | Description |
|
||||
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `condition` | You can programmatically show / hide fields based on what other fields are doing. [Click here](#conditional-logic) for more info. |
|
||||
| `components` | All field components can be completely and easily swapped out for custom components that you define. [Click here](#custom-components) for more info. |
|
||||
| `description` | Helper text to display with the field to provide more information for the editor user. [Click here](#description) for more info. |
|
||||
| `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. |
|
||||
| `width` | Restrict the width of a field. you can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a `Row` type where they can be organized horizontally. |
|
||||
| `style` | Attach raw CSS style properties to the root DOM element of a field. |
|
||||
| `className` | Attach a CSS class name to the root DOM element of a field. |
|
||||
| `readOnly` | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. |
|
||||
| `disabled` | If a field is `disabled`, it is completely omitted from the Admin panel. |
|
||||
| `disableBulkEdit` | Set `disableBulkEdit` to `true` to prevent fields from appearing in the select options when making edits for multiple documents. |
|
||||
| `disableListColumn` | Set `disableListColumn` to `true` to prevent fields from appearing in the list view column selector. |
|
||||
| `disableListFilter` | Set `disableListFilter` to `true` to prevent fields from appearing in the list view filter options. |
|
||||
| `hidden` | Setting a field's `hidden` property on its `admin` config will transform it into a `hidden` input type. Its value will still submit with the Admin panel's requests, but the field itself will not be visible to editors. |
|
||||
|
||||
### Custom components
|
||||
## Custom components
|
||||
|
||||
All Payload fields support the ability to swap in your own React components with ease. For more information, including examples, [click here](/docs/admin/components#fields).
|
||||
|
||||
### Conditional logic
|
||||
## Conditional logic
|
||||
|
||||
You can show and hide fields based on what other fields are doing by utilizing conditional logic on a field by field basis. The `condition` property on a field's admin config accepts a function which takes three arguments:
|
||||
|
||||
@@ -219,7 +222,7 @@ The `condition` function should return a boolean that will control if the field
|
||||
}
|
||||
```
|
||||
|
||||
### Default values
|
||||
## Default values
|
||||
|
||||
Fields can be prefilled with starting values using the `defaultValue` property. This is used in the admin UI and also on the backend as API requests will be populated with missing or undefined field values. You can assign the defaultValue directly in the field configuration or supply a function for dynamic behavior. Values assigned during a create request on the server are added before validation occurs.
|
||||
|
||||
@@ -249,7 +252,7 @@ const field = {
|
||||
You can use async defaultValue functions to fill fields with data from API requests.
|
||||
</Banner>
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
A description can be configured in three ways.
|
||||
|
||||
@@ -311,7 +314,7 @@ This example will display the number of characters allowed as the user types.
|
||||
|
||||
This component will count the number of characters entered, as well as display the path of the field.
|
||||
|
||||
### TypeScript
|
||||
## TypeScript
|
||||
|
||||
You can import the internal Payload `Field` type as well as other common field types as follows:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ label: Point
|
||||
order: 110
|
||||
desc: The Point field type stores coordinates in the database. Learn how to use Point field for geolocation and geometry.
|
||||
|
||||
keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -25,24 +25,24 @@ keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configurati
|
||||
|
||||
The data structure in the database matches the GeoJSON structure to represent point. The Payload APIs simplifies the object data to only the [longitude, latitude] location.
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. To support location queries, point index defaults to `2dsphere`, to disable the index set to `false`. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -50,7 +50,7 @@ _\* An asterisk denotes that a property is required._
|
||||
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
|
||||
</Banner>
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
@@ -69,6 +69,6 @@ export const ExampleCollection: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Querying
|
||||
## Querying
|
||||
|
||||
In order to do query based on the distance to another point, you can use the `near` operator. When querying using the near operator, the returned documents will be sorted by nearest first.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Radio Group Field
|
||||
label: Radio Group
|
||||
order: 120
|
||||
desc: The Radio field type allows for the selection of one value from a predefined set of possible values. Learn how to use Radio fields, see examples and options.
|
||||
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,24 +18,25 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
|
||||
caption="Admin panel screenshot of a Radio field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined.
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -48,7 +49,7 @@ _\* An asterisk denotes that a property is required._
|
||||
being used as a GraphQL enum.
|
||||
</Banner>
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Radio Group field type allows for the specification of the following `admin` properties:
|
||||
|
||||
@@ -56,7 +57,7 @@ In addition to the default [field admin config](/docs/fields/overview#admin-conf
|
||||
|
||||
The `layout` property allows for the radio group to be styled as a horizonally or vertically distributed list. The default value is `horizontal`.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Relationship Field
|
||||
label: Relationship
|
||||
order: 130
|
||||
desc: The Relationship field provides the ability to relate documents together. Learn how to use Relationship fields, see examples and options.
|
||||
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -12,10 +12,10 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
|
||||
</Banner>
|
||||
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/fields/relationship.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/relationship-dark.png"
|
||||
alt="Shows a relationship field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of a Relationship field"
|
||||
srcLight="https://payloadcms.com/images/docs/fields/relationship.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/relationship-dark.png"
|
||||
alt="Shows a relationship field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of a Relationship field"
|
||||
/>
|
||||
|
||||
**Example uses:**
|
||||
@@ -24,30 +24,30 @@ caption="Admin panel screenshot of a Relationship field"
|
||||
- To allow for an `Order` to feature a `placedBy` relationship to either an `Organization` or `User` collection
|
||||
- To assign `Category` documents to `Post` documents
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached. [Max Depth](/docs/getting-started/concepts#field-level-max-depth) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -58,7 +58,7 @@ _\* An asterisk denotes that a property is required._
|
||||
related documents that are returned by the API.
|
||||
</Banner>
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Relationship field type also
|
||||
allows for the following admin-specific properties:
|
||||
@@ -122,7 +122,7 @@ In this configuration:
|
||||
|
||||
Note: If `sortOptions` is not defined, the default sorting behavior of the Relationship field dropdown will be used.
|
||||
|
||||
### Filtering relationship options
|
||||
## Filtering relationship options
|
||||
|
||||
Options can be dynamically limited by supplying a [query constraint](/docs/queries/overview), which will be used both
|
||||
for validating input and filtering available relationships in the UI.
|
||||
@@ -131,15 +131,15 @@ The `filterOptions` property can either be a `Where` query, or a function return
|
||||
prevent all, or a `Where` query. When using a function, it will be
|
||||
called with an argument object with the following properties:
|
||||
|
||||
| Property | Description |
|
||||
|---------------|--------------------------------------------------------------------------------------|
|
||||
| `relationTo` | The `relationTo` to filter against (as defined on the field) |
|
||||
| `data` | An object of the full collection or global document currently being edited |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request |
|
||||
| `user` | The currently authenticated user object |
|
||||
| Property | Description |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
@@ -181,13 +181,13 @@ You can learn more about writing queries [here](/docs/queries/overview).
|
||||
<strong>payload/fields/validations</strong> in your validate function.
|
||||
</Banner>
|
||||
|
||||
### How the data is saved
|
||||
## How the data is saved
|
||||
|
||||
Given the variety of options possible within the `relationship` field type, the shape of the data needed for creating
|
||||
and updating these fields can vary. The following sections will describe the variety of data shapes that can arise from
|
||||
this field.
|
||||
|
||||
#### Has One
|
||||
### Has One
|
||||
|
||||
The most simple pattern of a relationship is to use `hasMany: false` with a `relationTo` that allows for only one type
|
||||
of collection.
|
||||
@@ -221,7 +221,7 @@ When querying documents in this collection via REST API, you could query as foll
|
||||
|
||||
`?where[owner][equals]=6031ac9e1289176380734024`.
|
||||
|
||||
#### Has One - Polymorphic
|
||||
### Has One - Polymorphic
|
||||
|
||||
Also known as **dynamic references**, in this configuration, the `relationTo` field is an array of Collection slugs that
|
||||
tells Payload which Collections are valid to reference.
|
||||
@@ -263,7 +263,7 @@ You can also query for documents where a field has a relationship to a specific
|
||||
|
||||
This query would return only documents that have an owner relationship to organizations.
|
||||
|
||||
#### Has Many
|
||||
### Has Many
|
||||
|
||||
The `hasMany` tells Payload that there may be more than one collection saved to the field.
|
||||
|
||||
@@ -287,10 +287,7 @@ To save the to `hasMany` relationship field we need to send an array of IDs:
|
||||
|
||||
```json
|
||||
{
|
||||
"owners": [
|
||||
"6031ac9e1289176380734024",
|
||||
"602c3c327b811235943ee12b"
|
||||
]
|
||||
"owners": ["6031ac9e1289176380734024", "602c3c327b811235943ee12b"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -298,7 +295,7 @@ When querying documents, the format does not change for arrays:
|
||||
|
||||
`?where[owners][equals]=6031ac9e1289176380734024`.
|
||||
|
||||
#### Has Many - Polymorphic
|
||||
### Has Many - Polymorphic
|
||||
|
||||
```ts
|
||||
{
|
||||
@@ -339,7 +336,7 @@ Querying is done in the same way as the earlier Polymorphic example:
|
||||
|
||||
`?where[owners.value][equals]=6031ac9e1289176380734024`.
|
||||
|
||||
#### Querying and Filtering Polymorphic Relationships
|
||||
### Querying and Filtering Polymorphic Relationships
|
||||
|
||||
Polymorphic and non-polymorphic relationships must be queried differently because of how the related data is stored and
|
||||
may be inconsistent across different collections. Because of this, filtering polymorphic relationship fields from the
|
||||
@@ -362,5 +359,6 @@ Since we are referencing multiple collections, the field you are querying on may
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a non-polymorphic relationship.
|
||||
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a
|
||||
non-polymorphic relationship.
|
||||
</Banner>
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Rich Text Field
|
||||
label: Rich Text
|
||||
order: 140
|
||||
desc: The Rich Text field allows dynamic content to be written through the Admin Panel. Learn how to use Rich Text fields, see examples and options.
|
||||
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,7 +18,7 @@ keywords: rich text, fields, config, configuration, documentation, Content Manag
|
||||
caption="Admin panel screenshot of a Rich Text field"
|
||||
/>
|
||||
|
||||
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
|
||||
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
|
||||
|
||||
Right now, Payload is officially supporting two rich text editors:
|
||||
|
||||
@@ -26,10 +26,17 @@ Right now, Payload is officially supporting two rich text editors:
|
||||
2. [Lexical](/docs/rich-text/lexical) - beta, where things will be moving
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Consistent with Payload's goal of making you learn as little of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em> rich text editor.</strong> Instead, you can invest your time and effort into learning the underlying open-source tools that will allow you to apply your learnings elsewhere as well.
|
||||
<strong>
|
||||
Consistent with Payload's goal of making you learn as little of Payload as possible, customizing
|
||||
and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em>{' '}
|
||||
rich text editor.
|
||||
</strong>
|
||||
|
||||
Instead, you can invest your time and effort into learning the underlying open-source tools that
|
||||
will allow you to apply your learnings elsewhere as well.
|
||||
</Banner>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -49,7 +56,7 @@ Right now, Payload is officially supporting two rich text editors:
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Rich Text editor allows for the following admin properties:
|
||||
|
||||
@@ -65,6 +72,6 @@ Set this property to `true` to hide this field's gutter within the admin panel.
|
||||
|
||||
Override the default text direction of the Admin panel for this field. Set to `true` to force right-to-left text direction.
|
||||
|
||||
### Editor-specific options
|
||||
## Editor-specific options
|
||||
|
||||
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.
|
||||
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Row Field
|
||||
label: Row
|
||||
order: 150
|
||||
desc: With the Row field you can arrange fields next to each other in the Admin Panel to help you customize your Dashboard.
|
||||
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,7 +18,7 @@ keywords: row, fields, config, configuration, documentation, Content Management
|
||||
caption="Admin panel screenshot of a Row field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -28,7 +28,7 @@ keywords: row, fields, config, configuration, documentation, Content Management
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Select Field
|
||||
label: Select
|
||||
order: 160
|
||||
desc: The Select field provides a dropdown-style interface for choosing options from a predefined list. Learn how to use Select fields, see examples and options.
|
||||
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,26 +18,28 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
|
||||
caption="Admin panel screenshot of a Select field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`dbName`** | Custom table name (if `hasMany` set to `true`) for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -50,7 +52,7 @@ _\* An asterisk denotes that a property is required._
|
||||
being used as a GraphQL enum.
|
||||
</Banner>
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Select field type also allows for the following admin-specific properties:
|
||||
|
||||
@@ -62,7 +64,7 @@ Set to `true` if you'd like this field to be clearable within the Admin UI.
|
||||
|
||||
Set to `true` if you'd like this field to be sortable within the Admin UI using drag and drop. (Only works when `hasMany` is set to `true`)
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
@@ -99,7 +101,7 @@ export const ExampleCollection: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Customization
|
||||
## Customization
|
||||
|
||||
The Select field UI component can be customized by providing a custom React component to the `components` object in the Base config.
|
||||
|
||||
@@ -122,7 +124,7 @@ export const CustomSelectField: Field = {
|
||||
],
|
||||
}),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -133,7 +135,7 @@ import * as React from 'react';
|
||||
import { SelectInput, useField } from 'payload/components/forms';
|
||||
import { useAuth } from 'payload/components/utilities';
|
||||
|
||||
type customSelectProps = {
|
||||
type CustomSelectProps = {
|
||||
path: string;
|
||||
options: {
|
||||
label: string;
|
||||
@@ -164,7 +166,7 @@ export const CustomSelectComponent: React.FC<CustomSelectProps> = ({ path, optio
|
||||
name={path}
|
||||
options={adjustedOptions}
|
||||
value={value}
|
||||
onChange={() => setValue(e.value)}
|
||||
onChange={(e) => setValue(e.value)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
@@ -174,9 +176,9 @@ export const CustomSelectComponent: React.FC<CustomSelectProps> = ({ path, optio
|
||||
If you are looking to create a dynamic select field, the following tutorial will walk you through the process of creating a custom select field that fetches its options from an external API.
|
||||
|
||||
<VideoDrawer
|
||||
id='Efn9OxSjA6Y'
|
||||
label='How to Create a Custom Select Field'
|
||||
drawerTitle='How to Create a Custom Select Field: A Step-by-Step Guide'
|
||||
id="Efn9OxSjA6Y"
|
||||
label="How to Create a Custom Select Field"
|
||||
drawerTitle="How to Create a Custom Select Field: A Step-by-Step Guide"
|
||||
/>
|
||||
|
||||
If you want to learn more about custom components check out the [Admin > Custom Component](/docs/admin/components#field-component) docs.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Tabs Field
|
||||
label: Tabs
|
||||
order: 170
|
||||
desc: The Tabs field is a great way to organize complex editing experiences into specific tab-based areas.
|
||||
keywords: tabs, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: tabs, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -19,7 +19,7 @@ keywords: tabs, fields, config, configuration, documentation, Content Management
|
||||
caption="Tabs field type used to separate Hero fields from Page Layout"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
@@ -27,7 +27,7 @@ keywords: tabs, fields, config, configuration, documentation, Content Management
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
#### Tab-specific Config
|
||||
### Tab-specific Config
|
||||
|
||||
Each tab must have either a `name` or `label` and the required `fields` array. You can also optionally pass a `description` to render within each individual tab.
|
||||
|
||||
@@ -41,7 +41,7 @@ Each tab must have either a `name` or `label` and the required `fields` array. Y
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Text Field
|
||||
label: Text
|
||||
order: 180
|
||||
desc: Text field types simply save a string to the database and provide the Admin panel with a text input. Learn how to use Text fields, see examples and options.
|
||||
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,30 +18,33 @@ keywords: text, fields, config, configuration, documentation, Content Management
|
||||
caption="Admin panel screenshot of a Text field and read-only Text field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
|
||||
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Text field type allows for the following `admin` properties:
|
||||
|
||||
@@ -57,7 +60,7 @@ Set this property to a string that will be used for browser autocomplete.
|
||||
|
||||
Override the default text direction of the Admin panel for this field. Set to `true` to force right-to-left text direction.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Textarea Field
|
||||
label: Textarea
|
||||
order: 190
|
||||
desc: Textarea field types save a string to the database, similar to the Text field type but equipped for longer text. Learn how to use Textarea fields, see examples and options.
|
||||
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -18,30 +18,30 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
|
||||
caption="Admin panel screenshot of a Textarea field and read-only Textarea field"
|
||||
/>
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
## Admin config
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), the Textarea field type allows for the following `admin` properties:
|
||||
|
||||
@@ -57,7 +57,7 @@ Set this property to a string that will be used for browser autocomplete.
|
||||
|
||||
Override the default text direction of the Admin panel for this field. Set to `true` to force right-to-left text direction.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: UI Field
|
||||
label: UI
|
||||
order: 200
|
||||
desc: UI fields are purely presentational and allow developers to customize the admin panel to a very fine degree, including adding actions and other functions.
|
||||
keywords: custom field, react component, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: custom field, react component, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -23,7 +23,7 @@ With this field, you can also inject custom `Cell` components that appear as add
|
||||
- Add a "view page" button into a Pages List view to give editors a shortcut to view a page on the frontend of the site
|
||||
- Build a "clear cache" button or similar mechanism to manually clear caches of specific documents
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -31,11 +31,12 @@ With this field, you can also inject custom `Cell` components that appear as add
|
||||
| **`label`** | Human-readable label for this UI field. |
|
||||
| **`admin.components.Field`** \* | React component to be rendered for this field within the Edit view. [More](/docs/admin/components/#field-component) |
|
||||
| **`admin.components.Cell`** | React component to be rendered as a Cell within collection List views. [More](/docs/admin/components/#field-component) |
|
||||
| **`admin.disableListColumn`** | Set `disableListColumn` to `true` to prevent the UI field from appearing in the list view column selector. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Upload Field
|
||||
label: Upload
|
||||
order: 210
|
||||
desc: Upload fields will allow a file to be uploaded, only from a collection supporting Uploads. Learn how to use Upload fields, see examples and options.
|
||||
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -20,10 +20,10 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
|
||||
</Banner>
|
||||
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/fields/upload.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/upload-dark.png"
|
||||
alt="Shows an upload field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of an Upload field"
|
||||
srcLight="https://payloadcms.com/images/docs/fields/upload.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/upload-dark.png"
|
||||
alt="Shows an upload field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of an Upload field"
|
||||
/>
|
||||
|
||||
**Example uses:**
|
||||
@@ -32,10 +32,10 @@ caption="Admin panel screenshot of an Upload field"
|
||||
- To allow for a `Product` to deliver a downloadable asset like PDF or MP3
|
||||
- To give a layout building block the ability to feature a background image
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
||||
@@ -56,7 +56,7 @@ caption="Admin panel screenshot of an Upload field"
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
@@ -76,7 +76,7 @@ export const ExampleCollection: CollectionConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Filtering upload options
|
||||
## Filtering upload options
|
||||
|
||||
Options can be dynamically limited by supplying a [query constraint](/docs/queries/overview), which will be used both
|
||||
for validating input and filtering available uploads in the UI.
|
||||
@@ -85,15 +85,15 @@ The `filterOptions` property can either be a `Where` query, or a function return
|
||||
prevent all, or a `Where` query. When using a function, it will be
|
||||
called with an argument object with the following properties:
|
||||
|
||||
| Property | Description |
|
||||
|---------------|--------------------------------------------------------------------------------------|
|
||||
| `relationTo` | The `relationTo` to filter against (as defined on the field) |
|
||||
| `data` | An object of the full collection or global document currently being edited |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request |
|
||||
| `user` | The currently authenticated user object |
|
||||
| Property | Description |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
|
||||
**Example:**
|
||||
## Example
|
||||
|
||||
```ts
|
||||
const uploadField = {
|
||||
|
||||
@@ -3,18 +3,18 @@ title: Payload Concepts
|
||||
label: Concepts
|
||||
order: 20
|
||||
desc: Payload is based around a small and intuitive set of concepts. Key concepts include collections, globals, fields and more.
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Payload is based around a small and intuitive set of concepts. Before starting to work with Payload, it's a good idea to familiarize yourself with the following:
|
||||
|
||||
### Config
|
||||
## Config
|
||||
|
||||
<Banner type="info">The Payload config is where you configure everything that Payload does.</Banner>
|
||||
|
||||
By default, the Payload config lives in the root folder of your code and is named `payload.config.js` (`payload.config.ts` if you're using TypeScript), but you can customize its name and where you store it. You can write full functions and even full React components right into your config.
|
||||
|
||||
### Collections
|
||||
## Collections
|
||||
|
||||
<Banner type="info">
|
||||
A Collection represents a type of content that Payload will store and can contain many documents.
|
||||
@@ -24,7 +24,7 @@ Collections define the shape of your data as well as all functionalities attache
|
||||
|
||||
They can represent anything you can store in a database - for example - pages, posts, users, people, orders, categories, events, customers, transactions, and anything else your app needs.
|
||||
|
||||
### Globals
|
||||
## Globals
|
||||
|
||||
<Banner type="info">
|
||||
A Global is a "one-off" piece of content that is perfect for storing navigational structures,
|
||||
@@ -33,7 +33,7 @@ They can represent anything you can store in a database - for example - pages, p
|
||||
|
||||
Globals are in many ways similar to Collections, but there is only ever **one** instance of a Global, whereas Collections can contain many documents.
|
||||
|
||||
### Fields
|
||||
## Fields
|
||||
|
||||
<Banner type="info">
|
||||
Fields are the building blocks of Payload. Collections and Globals both use Fields to define the
|
||||
@@ -42,7 +42,7 @@ Globals are in many ways similar to Collections, but there is only ever **one**
|
||||
|
||||
Payload comes with [many different field types](../fields/overview) that give you a ton of flexibility while designing your API. Each Field type has its own potential properties that allow you to customize how they work.
|
||||
|
||||
### Hooks
|
||||
## Hooks
|
||||
|
||||
<Banner type="info">
|
||||
Hooks are where you can "tie in" to existing Payload actions to perform your own additional logic
|
||||
@@ -53,7 +53,7 @@ Hooks are an extremely powerful concept and are central to extending and customi
|
||||
|
||||
There are many more potential reasons to use Hooks. For more, visit the [Hooks documentation](/docs/hooks/overview).
|
||||
|
||||
### Access Control
|
||||
## Access Control
|
||||
|
||||
<Banner type="info">
|
||||
Access Control refers to Payload's system of defining who can do what to your API.
|
||||
@@ -63,7 +63,7 @@ Access Control is extremely powerful but easy and intuitive to manage. You can e
|
||||
|
||||
For more, visit the [Access Control documentation](/docs/access-control/overview).
|
||||
|
||||
### Depth
|
||||
## Depth
|
||||
|
||||
<Banner type="info">
|
||||
"Depth" gives you control over how many levels down related documents should be automatically
|
||||
@@ -156,6 +156,28 @@ To populate `user.author.department` in it's entirety you could specify `?depth=
|
||||
}
|
||||
```
|
||||
|
||||
### Field-level max depth
|
||||
|
||||
Fields like relationships or uploads can have a `maxDepth` property that limits the depth of the population for that field. Here are some examples:
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 1
|
||||
`maxDepth`: undefined
|
||||
|
||||
In this case, the field would be populated to 9 levels of population.
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 0
|
||||
`maxDepth`: 2
|
||||
|
||||
In this case, the field would be populated to 2 levels of population, despite there being a remaining depth of 8.
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 2
|
||||
`maxDepth`: 1
|
||||
|
||||
In this case, the field would not be populated, as the current depth (2) has exceeded the `maxDepth` for this field (1).
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
|
||||
@@ -3,15 +3,15 @@ title: Installation
|
||||
label: Installation
|
||||
order: 30
|
||||
desc: To quickly get started with Payload, simply run npx create-payload-app or install from scratch.
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
#### Software Requirements
|
||||
## Software Requirements
|
||||
|
||||
Payload requires the following software:
|
||||
|
||||
- Any JavaScript package manager (Yarn, NPM, or pnpm)
|
||||
- Node.js version 16+
|
||||
- Node.js version 18+
|
||||
- Any [compatible database](/docs/database/overview) (MongoDB or Postgres)
|
||||
|
||||
<Banner type="warning">
|
||||
@@ -30,7 +30,7 @@ Then just follow the prompts! You'll get set up with a new folder and a function
|
||||
|
||||
## Adding to an existing app
|
||||
|
||||
Adding Payload to either a new or existing TypeScript + Express app is super straightforward. To add to an existing app, just run `npm install --save --legacy-peer-deps payload`.
|
||||
Adding Payload to either a new or existing TypeScript + Next.js app is super straightforward. To add to an existing app, just run `npm install --save --legacy-peer-deps payload`.
|
||||
|
||||
From there, the first step is writing a baseline config. Create a new `payload.config.ts` in your project's `/src` directory (or whatever your root TS dir is). The simplest config contains the following:
|
||||
|
||||
@@ -48,7 +48,7 @@ Write the above code into your newly created config file. This baseline config w
|
||||
|
||||
Although this is just the bare minimum config, there are _many_ more options that you can control here. To reference the full config and all of its options, [click here](/docs/configuration/overview).
|
||||
|
||||
### Server
|
||||
## Server
|
||||
|
||||
Now that you've got a baseline Payload config, it's time to initialize Payload. It requires an Express server that you provide, so if you're not familiar with how to set up a baseline Express server, please read up on exactly what Express is and why to use it. Express' own [Documentation](https://expressjs.com/en/starter/hello-world.html) is a good place to start. Otherwise, follow along below for how to build your own Express server to use with Payload.
|
||||
|
||||
@@ -62,9 +62,7 @@ import express from 'express'
|
||||
const app = express()
|
||||
|
||||
app.listen(3000, async () => {
|
||||
console.log(
|
||||
"Express is now listening for incoming connections on port 3000."
|
||||
)
|
||||
console.log('Express is now listening for incoming connections on port 3000.')
|
||||
})
|
||||
```
|
||||
|
||||
@@ -86,9 +84,7 @@ const start = async () => {
|
||||
})
|
||||
|
||||
app.listen(3000, async () => {
|
||||
console.log(
|
||||
"Express is now listening for incoming connections on port 3000."
|
||||
)
|
||||
console.log('Express is now listening for incoming connections on port 3000.')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -104,52 +100,54 @@ PAYLOAD_SECRET=your-payload-secret
|
||||
|
||||
Here is a list of all properties available to pass through `payload.init`:
|
||||
|
||||
##### secret
|
||||
#### secret
|
||||
|
||||
**Required**. This is a secure string that will be used to authenticate with Payload. It can be random but should be at least 14 characters and be very difficult to guess.
|
||||
|
||||
Payload uses this secret key to generate secure user tokens (JWT). Behind the scenes, we do not use your secret key to encrypt directly - instead, we first take the secret key and create an encrypted string using the SHA-256 hash function. Then, we reduce the encrypted string to its first 32 characters. This final value is what Payload uses for encryption.
|
||||
|
||||
##### config
|
||||
#### config
|
||||
|
||||
Allows you to pass your config directly to the onInit function. The config passed here should match the payload.config file.
|
||||
|
||||
##### disableOnInit
|
||||
#### disableOnInit
|
||||
|
||||
A boolean that disables running your `onInit` function when Payload starts up.
|
||||
|
||||
##### disableDBConnect
|
||||
#### disableDBConnect
|
||||
|
||||
A boolean that disables the database connection when Payload starts up.
|
||||
|
||||
##### email
|
||||
#### email
|
||||
|
||||
An object used to configure SMTP. [Read more](/docs/email/overview).
|
||||
|
||||
##### express
|
||||
#### express
|
||||
|
||||
This is your Express app as shown above. Payload will tie into your existing `app` and scope all of its functionalities to sub-routers. By default, Payload will add an `/admin` router and an `/api` router, but you can customize these paths.
|
||||
|
||||
##### local
|
||||
#### local
|
||||
|
||||
A boolean that when set to `true` tells Payload to start in local-only mode which will bypass setting up API routes. When set to `true`, `express` is not required. This is useful when running scripts that need to use Payload's [local-api](/docs/local-api/overview).
|
||||
|
||||
##### loggerDestination
|
||||
#### loggerDestination
|
||||
|
||||
Specify destination stream for the built-in Pino logger that Payload uses for internal logging. See [Pino Docs](https://getpino.io/#/docs/api?id=pino-destination) for more info on what is available.
|
||||
|
||||
##### loggerOptions
|
||||
#### loggerOptions
|
||||
|
||||
Specify options for the built-in Pino logger that Payload uses for internal logging. See [Pino Docs](https://getpino.io/#/docs/api?id=options) for more info on what is available.
|
||||
|
||||
##### onInit
|
||||
#### onInit
|
||||
|
||||
A function that is called immediately following startup that receives the Payload instance as it's only argument.
|
||||
|
||||
### Test it out
|
||||
## Test it out
|
||||
|
||||
After you've gotten this far, it's time to boot up Payload. Start your project in your application's folder to get going.
|
||||
|
||||
After it starts, you can go to `http://localhost:3000/admin` to create your first Payload user!
|
||||
|
||||
### Docker
|
||||
## Docker
|
||||
|
||||
Looking to deploy Payload with Docker? New projects with `create-payload-app` come with a Dockerfile and docker-compose.yml file ready to go. Examples of these files can be seen in our [Deployment docs](/docs/production/deployment#docker).
|
||||
|
||||
@@ -3,7 +3,7 @@ title: What is Payload?
|
||||
label: What is Payload?
|
||||
order: 10
|
||||
desc: Payload is a next-gen headless Content Management System (CMS) and application framework.
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
<YouTube
|
||||
@@ -17,7 +17,8 @@ development process, but importantly, stay out of your way as your apps get more
|
||||
<Banner type="success">
|
||||
<strong>Payload 2.0 has been released!</strong>
|
||||
<br />
|
||||
Includes Postgres support, Live Preview, Lexical Editor, and more. <a href="/blog/payload-2-0">Read the announcement</a>.
|
||||
Includes Postgres support, Live Preview, Lexical Editor, and more.{' '}
|
||||
<a href="/blog/payload-2-0">Read the announcement</a>.
|
||||
</Banner>
|
||||
|
||||
Out of the box, Payload gives you a lot of the things that you often need when developing a new website, web app, or native app:
|
||||
@@ -37,7 +38,7 @@ In this way, the CMS can ensure that its content editing experience is highly po
|
||||
|
||||
At this point this concept is [widely](https://en.wikipedia.org/wiki/Headless_content_management_system) [discussed](https://css-tricks.com/what-is-a-headless-cms/) online, and for good reason. The web has become more complicated and with complexity comes the demand for developers to better structure their code. The rise of interface libraries like React and Vue are now the de-facto standard for building modern applications and traditional content management systems are often not designed to make use of them.
|
||||
|
||||
### Why Payload?
|
||||
## Why Payload?
|
||||
|
||||
The team behind Payload has been building websites and apps with existing content management systems and application frameworks for over a decade. We know what works and what doesn't about each of the existing solutions, and to this day have found no silver bullet solution.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Adding your own Queries and Mutations
|
||||
label: Custom Queries and Mutations
|
||||
order: 20
|
||||
desc: Payload allows you to add your own GraphQL queries and mutations, simply set up GraphQL in your main Payload config by following these instructions.
|
||||
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
You can add your own GraphQL queries and mutations to Payload, making use of all the types that Payload has defined for you.
|
||||
@@ -25,11 +25,11 @@ This is Payload's GraphQL dependency. You should not install your own copy of Gr
|
||||
|
||||
This is a copy of the currently running Payload instance, which provides you with existing GraphQL types for all of your Collections and Globals - among other things.
|
||||
|
||||
##### Return value
|
||||
## Return value
|
||||
|
||||
Both `graphQL.queries` and `graphQL.mutations` functions should return an object with properties equal to your newly written GraphQL queries and mutations.
|
||||
|
||||
### Example
|
||||
## Example
|
||||
|
||||
`payload.config.js`:
|
||||
|
||||
@@ -68,7 +68,7 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
### Resolver function
|
||||
## Resolver function
|
||||
|
||||
In your resolver, make sure you set `depth: 0` if you're returning data directly from the local API so that GraphQL can correctly resolve queries to nested values such as relationship data.
|
||||
|
||||
@@ -96,7 +96,7 @@ An object containing the `req` and `res` objects that will provide you with the
|
||||
|
||||
Contextual information about the currently running GraphQL operation. You can get schema information from this as well as contextual information about where this resolver function is being run.
|
||||
|
||||
### Types
|
||||
## Types
|
||||
|
||||
We've exposed a few types and utilities to help you extend the API further. Payload uses the GraphQL.js package for which you can view the full list of available types in the [official documentation](https://graphql.org/graphql-js/type/).
|
||||
|
||||
@@ -138,7 +138,7 @@ graphQL?: {
|
||||
}
|
||||
```
|
||||
|
||||
### Best practices
|
||||
## Best practices
|
||||
|
||||
There are a few ways to structure your code, we recommend using a dedicated `graphql` directory so you can keep all of your logic in one place. You have total freedom of how you want to structure this but a common pattern is to group functions by type and with their resolver.
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ title: GraphQL Schema
|
||||
label: GraphQL Schema
|
||||
order: 30
|
||||
desc: Output your own GraphQL schema based on your collections and globals to a file.
|
||||
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
When working with GraphQL it is useful to have the schema for development of other projects that need to call on your GraphQL endpoint. In Payload the schema is controlled by your collections and globals and is made available to the developer or third parties, it is not necessary for developers using Payload to write schema types manually.
|
||||
|
||||
### Schema generation script
|
||||
## Schema generation script
|
||||
|
||||
Run the following command in a Payload project to generate your project's GraphQL schema from Payload:
|
||||
|
||||
@@ -16,20 +16,7 @@ Run the following command in a Payload project to generate your project's GraphQ
|
||||
payload generate:graphQLSchema
|
||||
```
|
||||
|
||||
You can run this command whenever you need to regenerate your GraphQL schema and output it to a file, and then you can use the schema for writing your own GraphQL elsewhere in other projects.
|
||||
|
||||
### Custom output file path
|
||||
|
||||
```js
|
||||
{
|
||||
// the remainder of your config
|
||||
graphQL: {
|
||||
schemaOutputFile: path.resolve(__dirname, './graphql/schema.graphql'),
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Field Schemas
|
||||
## Custom Field Schemas
|
||||
|
||||
For `array`, `block`, `group` and named `tab` fields, you can generate top level reusable interfaces. The following group field config:
|
||||
|
||||
@@ -69,7 +56,7 @@ type Collection1 {
|
||||
|
||||
The above example outputs all your definitions to a file relative from your payload config as `./graphql/schema.graphql`. By default, the file will be output to your current working directory as `schema.graphql`.
|
||||
|
||||
#### Adding an NPM script
|
||||
### Adding an NPM script
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important</strong>
|
||||
|
||||
@@ -3,7 +3,7 @@ title: GraphQL Overview
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: Payload ships with a fully featured and extensible GraphQL API, which can be used in addition to the REST and Local APIs to give you more flexibility.
|
||||
keywords: graphql, resolvers, mutations, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: graphql, resolvers, mutations, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
In addition to its REST and Local APIs, Payload ships with a fully featured and extensible GraphQL API.
|
||||
@@ -16,14 +16,13 @@ The labels you provide for your Collections and Globals are used to name the Gra
|
||||
|
||||
At the top of your Payload config you can define all the options to manage GraphQL.
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |
|
||||
| `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground, defaults to true. [More](/docs/graphql/overview#graphql-playground) |
|
||||
| `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. |
|
||||
| `schemaOutputFile` | A string for the file path used by the generate schema command. Defaults to `graphql.schema` next to `payload.config.ts` [More](/docs/graphql/graphql-schema) |
|
||||
| Option | Description |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |
|
||||
| `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground, defaults to true. [More](/docs/graphql/overview#graphql-playground) |
|
||||
| `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. |
|
||||
|
||||
## Collections
|
||||
|
||||
@@ -43,11 +42,12 @@ export const PublicUser: CollectionConfig = {
|
||||
|
||||
**Payload will automatically open up the following queries:**
|
||||
|
||||
| Query Name | Operation |
|
||||
| ------------------ | ------------------- |
|
||||
| **`PublicUser`** | `findByID` |
|
||||
| **`PublicUsers`** | `find` |
|
||||
| **`mePublicUser`** | `me` auth operation |
|
||||
| Query Name | Operation |
|
||||
| ------------------ | ------------------- |
|
||||
| **`PublicUser`** | `findByID` |
|
||||
| **`PublicUsers`** | `find` |
|
||||
| **`countPublicUsers`** | `count` |
|
||||
| **`mePublicUser`** | `me` auth operation |
|
||||
|
||||
**And the following mutations:**
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Collection Hooks
|
||||
label: Collections
|
||||
order: 20
|
||||
desc: You can add hooks to any Collection, several hook types are available including beforeChange, afterRead, afterDelete and more.
|
||||
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Collections feature the ability to define the following hooks:
|
||||
@@ -75,6 +75,7 @@ import { CollectionBeforeOperationHook } from 'payload/types'
|
||||
const beforeOperationHook: CollectionBeforeOperationHook = async ({
|
||||
args, // original arguments passed into the operation
|
||||
operation, // name of the operation
|
||||
req, // full Request object
|
||||
}) => {
|
||||
return args // return modified operation arguments as necessary
|
||||
}
|
||||
@@ -95,7 +96,7 @@ import { CollectionBeforeValidateHook } from 'payload/types'
|
||||
|
||||
const beforeValidateHook: CollectionBeforeValidateHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
originalDoc, // original document
|
||||
}) => {
|
||||
@@ -112,7 +113,7 @@ import { CollectionBeforeChangeHook } from 'payload/types'
|
||||
|
||||
const beforeChangeHook: CollectionBeforeChangeHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
originalDoc, // original document
|
||||
}) => {
|
||||
@@ -129,7 +130,7 @@ import { CollectionAfterChangeHook } from 'payload/types'
|
||||
|
||||
const afterChangeHook: CollectionAfterChangeHook = async ({
|
||||
doc, // full document data
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
previousDoc, // document data before updating the collection
|
||||
operation, // name of the operation ie. 'create', 'update'
|
||||
}) => {
|
||||
@@ -146,7 +147,7 @@ import { CollectionBeforeReadHook } from 'payload/types'
|
||||
|
||||
const beforeReadHook: CollectionBeforeReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
query, // JSON formatted query
|
||||
}) => {
|
||||
return doc
|
||||
@@ -162,7 +163,7 @@ import { CollectionAfterReadHook } from 'payload/types'
|
||||
|
||||
const afterReadHook: CollectionAfterReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
query, // JSON formatted query
|
||||
findMany, // boolean to denote if this hook is running against finding one, or finding many
|
||||
}) => {
|
||||
@@ -178,7 +179,7 @@ Runs before the `delete` operation. Returned values are discarded.
|
||||
import { CollectionBeforeDeleteHook } from 'payload/types';
|
||||
|
||||
const beforeDeleteHook: CollectionBeforeDeleteHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
id, // id of document to delete
|
||||
}) => {...}
|
||||
```
|
||||
@@ -191,7 +192,7 @@ Runs immediately after the `delete` operation removes records from the database.
|
||||
import { CollectionAfterDeleteHook } from 'payload/types';
|
||||
|
||||
const afterDeleteHook: CollectionAfterDeleteHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
id, // id of document to delete
|
||||
doc, // deleted document
|
||||
}) => {...}
|
||||
@@ -209,6 +210,7 @@ import { CollectionAfterOperationHook } from 'payload/types'
|
||||
const afterOperationHook: CollectionAfterOperationHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
operation, // name of the operation
|
||||
req, // full Request object
|
||||
result, // the result of the operation, before modifications
|
||||
}) => {
|
||||
return result // return modified result as necessary
|
||||
@@ -223,7 +225,7 @@ For auth-enabled Collections, this hook runs during `login` operations where a u
|
||||
import { CollectionBeforeLoginHook } from 'payload/types'
|
||||
|
||||
const beforeLoginHook: CollectionBeforeLoginHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
user, // user being logged in
|
||||
}) => {
|
||||
return user
|
||||
@@ -238,7 +240,7 @@ For auth-enabled Collections, this hook runs after successful `login` operations
|
||||
import { CollectionAfterLoginHook } from 'payload/types';
|
||||
|
||||
const afterLoginHook: CollectionAfterLoginHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
user, // user that was logged in
|
||||
token, // user token
|
||||
}) => {...}
|
||||
@@ -252,7 +254,7 @@ For auth-enabled Collections, this hook runs after `logout` operations.
|
||||
import { CollectionAfterLogoutHook } from 'payload/types';
|
||||
|
||||
const afterLogoutHook: CollectionAfterLogoutHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
@@ -264,8 +266,8 @@ For auth-enabled Collections, this hook runs after `refresh` operations.
|
||||
import { CollectionAfterRefreshHook } from 'payload/types';
|
||||
|
||||
const afterRefreshHook: CollectionAfterRefreshHook = async ({
|
||||
req, // full express request
|
||||
res, // full express response
|
||||
req, // full Request object
|
||||
res, // full Response object
|
||||
token, // newly refreshed user token
|
||||
}) => {...}
|
||||
```
|
||||
@@ -278,7 +280,7 @@ For auth-enabled Collections, this hook runs after `me` operations.
|
||||
import { CollectionAfterMeHook } from 'payload/types';
|
||||
|
||||
const afterMeHook: CollectionAfterMeHook = async ({
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
response, // response to return
|
||||
}) => {...}
|
||||
```
|
||||
@@ -290,13 +292,11 @@ For auth-enabled Collections, this hook runs after successful `forgotPassword` o
|
||||
```ts
|
||||
import { CollectionAfterForgotPasswordHook } from 'payload/types'
|
||||
|
||||
const afterLoginHook: CollectionAfterForgotPasswordHook = async ({
|
||||
req, // full express request
|
||||
user, // user being logged in
|
||||
token, // user token
|
||||
}) => {
|
||||
return user
|
||||
}
|
||||
const afterForgotPasswordHook: CollectionAfterForgotPasswordHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
context,
|
||||
collection, // The collection which this hook is being run on
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
@@ -3,10 +3,11 @@ title: Field Hooks
|
||||
label: Fields
|
||||
order: 30
|
||||
desc: Hooks can be added to any fields, and optionally modify the return value of the field before the operation continues.
|
||||
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up functionalities to be easily reusable across your projects.
|
||||
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up
|
||||
functionalities to be easily reusable across your projects.
|
||||
|
||||
**Example use cases include:**
|
||||
|
||||
@@ -20,6 +21,7 @@ Field-level hooks offer incredible potential for encapsulating your logic. They
|
||||
|
||||
- [beforeValidate](#beforevalidate)
|
||||
- [beforeChange](#beforechange)
|
||||
- beforeDuplicate(#beforeduplicate)
|
||||
- [afterChange](#afterchange)
|
||||
- [afterRead](#afterread)
|
||||
|
||||
@@ -37,6 +39,7 @@ const ExampleField: Field = {
|
||||
hooks: {
|
||||
beforeValidate: [(args) => {...}],
|
||||
beforeChange: [(args) => {...}],
|
||||
beforeDuplicate: [(args) => {...}],
|
||||
afterChange: [(args) => {...}],
|
||||
afterRead: [(args) => {...}],
|
||||
}
|
||||
@@ -46,7 +49,8 @@ const ExampleField: Field = {
|
||||
|
||||
## Arguments and return values
|
||||
|
||||
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on which field hook you are utilizing.
|
||||
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on
|
||||
which field hook you are utilizing.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
@@ -62,17 +66,17 @@ All field-level hooks are formatted to accept the same arguments, although some
|
||||
Field Hooks receive one `args` argument that contains the following properties:
|
||||
|
||||
| Option | Description |
|
||||
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The data passed to update the document within `create` and `update` operations, and the full document itself in the `afterRead` hook. |
|
||||
| **`siblingData`** | The sibling data passed to a field that the hook is running against. |
|
||||
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many within the `afterRead` hook. |
|
||||
| **`operation`** | A string relating to which operation the field type is currently executing within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
|
||||
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
|
||||
| **`previousDoc`** | The document before changes were applied, only in `afterChange` hooks. |
|
||||
| **`previousSiblingDoc`** | The sibling data from the previous document in `afterChange` hook. |
|
||||
| **`req`** | The Express `request` object. It is mocked for Local API operations. |
|
||||
| **`previousSiblingDoc`** | The sibling data of the document before changes being applied, only in `beforeChange` and `afterChange` hook. |
|
||||
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It is mocked for Local API operations. |
|
||||
| **`value`** | The value of the field. |
|
||||
| **`previousValue`** | The previous value of the field, before changes were applied, only in `afterChange` hooks. |
|
||||
| **`previousValue`** | The previous value of the field, before changes, only in `beforeChange` and `afterChange` hooks. |
|
||||
| **`context`** | Context passed to this hook. More info can be found under [Context](/docs/hooks/context) |
|
||||
| **`field`** | The field which the hook is running against. |
|
||||
| **`collection`** | The collection which the field belongs to. If the field belongs to a global, this will be null. |
|
||||
@@ -80,7 +84,8 @@ Field Hooks receive one `args` argument that contains the following properties:
|
||||
|
||||
#### Return value
|
||||
|
||||
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may optionally return the value that should be used within the field.
|
||||
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may
|
||||
optionally return the value that should be used within the field.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important</strong>
|
||||
@@ -92,11 +97,14 @@ All field hooks can optionally modify the return value of the field before the o
|
||||
|
||||
## Examples of Field Hooks
|
||||
|
||||
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the true potential of field-level hooks lies in their adaptability to a wide array of use cases.
|
||||
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the
|
||||
flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the
|
||||
true potential of field-level hooks lies in their adaptability to a wide array of use cases.
|
||||
|
||||
### beforeValidate
|
||||
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes validation.
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes
|
||||
validation.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -105,19 +113,25 @@ const usernameField: Field = {
|
||||
name: 'username',
|
||||
type: 'text',
|
||||
hooks: {
|
||||
beforeValidate: [({ value }) => {
|
||||
// Trim whitespace and convert to lowercase
|
||||
return value.trim().toLowerCase()
|
||||
}],
|
||||
}
|
||||
beforeValidate: [
|
||||
({ value }) => {
|
||||
// Trim whitespace and convert to lowercase
|
||||
return value.trim().toLowerCase()
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is stored in a consistent format in the database.
|
||||
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of
|
||||
the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is
|
||||
stored in a consistent format in the database.
|
||||
|
||||
### beforeChange
|
||||
|
||||
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage, you can be confident that the field data that will be saved to the document is valid in accordance to your field validations.
|
||||
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage,
|
||||
you can be confident that the field data that will be saved to the document is valid in accordance to your field
|
||||
validations.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -126,21 +140,26 @@ const emailField: Field = {
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
hooks: {
|
||||
beforeChange: [({ value, operation }) => {
|
||||
if (operation === 'create') {
|
||||
// Perform additional validation or transformation for 'create' operation
|
||||
}
|
||||
return value
|
||||
}],
|
||||
}
|
||||
beforeChange: [
|
||||
({ value, operation }) => {
|
||||
if (operation === 'create') {
|
||||
// Perform additional validation or transformation for 'create' operation
|
||||
}
|
||||
return value
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs additional validation or transformation on the email field value. This allows for operation-specific logic to be applied to the field.
|
||||
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs
|
||||
additional validation or transformation on the email field value. This allows for operation-specific logic to be applied
|
||||
to the field.
|
||||
|
||||
### afterChange
|
||||
|
||||
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful for post-processing or triggering side effects based on the new value of the field.
|
||||
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful
|
||||
for post-processing or triggering side effects based on the new value of the field.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -151,25 +170,33 @@ const membershipStatusField: Field = {
|
||||
options: [
|
||||
{ label: 'Standard', value: 'standard' },
|
||||
{ label: 'Premium', value: 'premium' },
|
||||
{ label: 'VIP', value: 'vip' }
|
||||
{ label: 'VIP', value: 'vip' },
|
||||
],
|
||||
hooks: {
|
||||
afterChange: [({ value, previousValue, req }) => {
|
||||
if (value !== previousValue) {
|
||||
// Log or perform an action when the membership status changes
|
||||
console.log(`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`)
|
||||
// Here, you can implement actions that could track conversions from one tier to another
|
||||
}
|
||||
}],
|
||||
}
|
||||
afterChange: [
|
||||
({ value, previousValue, req }) => {
|
||||
if (value !== previousValue) {
|
||||
// Log or perform an action when the membership status changes
|
||||
console.log(
|
||||
`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`,
|
||||
)
|
||||
// Here, you can implement actions that could track conversions from one tier to another
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or notifying them about changes in their membership benefits.
|
||||
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their
|
||||
membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it
|
||||
logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or
|
||||
notifying them about changes in their membership benefits.
|
||||
|
||||
### afterRead
|
||||
|
||||
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or transforming the field data for output.
|
||||
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or
|
||||
transforming the field data for output.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -178,17 +205,45 @@ const dateField: Field = {
|
||||
name: 'createdAt',
|
||||
type: 'date',
|
||||
hooks: {
|
||||
afterRead: [({ value }) => {
|
||||
// Format date for display
|
||||
return new Date(value).toLocaleDateString()
|
||||
afterRead: [
|
||||
({ value }) => {
|
||||
// Format date for display
|
||||
return new Date(value).toLocaleDateString()
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format
|
||||
using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more
|
||||
user-friendly.
|
||||
|
||||
### beforeDuplicate
|
||||
|
||||
The `beforeDuplicate` field hook is called on each locale (when using localization), when duplicating a document. It may be used when documents having the
|
||||
exact same properties may cause issue. This gives you a way to avoid duplicate names on `unique`, `required` fields or when external systems expect non-repeating values on documents.
|
||||
|
||||
This hook gets called after `beforeChange` hooks are called and before the document is saved to the database.
|
||||
|
||||
By Default, unique and required text fields Payload will append "- Copy" to the original document value. The default is not added if your field has its own, you must return non-unique values from your beforeDuplicate hook to avoid errors or enable the `disableDuplicate` option on the collection.
|
||||
Here is an example of a number field with a hook that increments the number to avoid unique constraint errors when duplicating a document:
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
|
||||
const numberField: Field = {
|
||||
name: 'number',
|
||||
type: 'number',
|
||||
hooks: {
|
||||
// increment existing value by 1
|
||||
beforeDuplicate: [({ value }) => {
|
||||
return (value ?? 0) + 1
|
||||
}],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more user-friendly.
|
||||
|
||||
|
||||
## TypeScript
|
||||
|
||||
Payload exports a type for field hooks which can be accessed and used as follows:
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Global Hooks
|
||||
label: Globals
|
||||
order: 40
|
||||
desc: Hooks can be added to any Global and allow you to validate data, flatten locales, hide protected fields, remove fields and more.
|
||||
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
Globals feature the ability to define the following hooks:
|
||||
@@ -47,7 +47,7 @@ import { GlobalBeforeValidateHook } from 'payload/types'
|
||||
|
||||
const beforeValidateHook: GlobalBeforeValidateHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
originalDoc, // original document
|
||||
}) => {
|
||||
return data // Return data to update the document with
|
||||
@@ -63,7 +63,7 @@ import { GlobalBeforeChangeHook } from 'payload/types'
|
||||
|
||||
const beforeChangeHook: GlobalBeforeChangeHook = async ({
|
||||
data, // incoming data to update or create with
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
originalDoc, // original document
|
||||
}) => {
|
||||
return data // Return data to update the document with
|
||||
@@ -80,7 +80,7 @@ import { GlobalAfterChangeHook } from 'payload/types'
|
||||
const afterChangeHook: GlobalAfterChangeHook = async ({
|
||||
doc, // full document data
|
||||
previousDoc, // document data before updating the collection
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
}) => {
|
||||
return data
|
||||
}
|
||||
@@ -95,7 +95,7 @@ import { GlobalBeforeReadHook } from 'payload/types'
|
||||
|
||||
const beforeReadHook: GlobalBeforeReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
@@ -108,7 +108,7 @@ import { GlobalAfterReadHook } from 'payload/types'
|
||||
|
||||
const afterReadHook: GlobalAfterReadHook = async ({
|
||||
doc, // full document data
|
||||
req, // full express request
|
||||
req, // full Request object
|
||||
findMany, // boolean to denote if this hook is running against finding one, or finding many (useful in versions)
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user