Hey guys!
I've been working a feature for a client that wants to use 1 payload instance for all his sites.
So far I added a sites
collection and every collection (such as pages
) has a site
relation.
I've added a Context for setting your currently active site:
import React, {
useState, createContext, useContext, useEffect,
} from 'react';
const Context = createContext({
currentSite: null,
setCurrentSite: () => {},
} as SiteContext);
export const SiteProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [currentSite, setCurrentSite] = useState<string | null>();
useEffect(() => {
const site = localStorage.getItem('currentSite');
if (site) {
setCurrentSite(site);
}
});
const setSite = (site: string | null) => {
localStorage.setItem('currentSite', site);
setCurrentSite(site);
}
return (
<Context.Provider value={{
currentSite,
setCurrentSite: setSite,
}}>
{children}
</Context.Provider>
);
};
class SiteContext {
currentSite: string | null;
setCurrentSite: (string) => void;
}
type UseSite = () => SiteContext;
export const useSite: UseSite = () => useContext(Context);
And added a simple dropdown below the logo to pick one of the sites.
Now I want to enable the "collection.filters.where.site = currentSite
" filter by default on some of the collections, but I have trouble finding where to do this. Any tips?
Hey @falko100 — that type of "filter" would be referred to as a query constraint, and that is generally accomplished via some backend logic in either a field hook or an access control operation.
There are lots of ways to do this - but I think how I'd do it is persist something to the user when you switch the selected site - like... a select
field on the user or similar.
And then write all your access control to look at which site the user has selected, and return your query constraint based on that. Does that make sense?
Ahh perfect. I was close but got confused.
I finally put it here:
const Pages: CollectionConfig = {
slug: 'pages',
access: {
read: ({ req: { user }}) => {
if (user) {
return {
site: {
equals: user.currentSite.id,
}
}
}
return true;
},
...
},
My problem was that I was trying to do this all in the frontend.
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.