#Customary way of setting up Payload?

6 messages · Page 1 of 1 (latest)

fresh agate
#

I'm working on my own template, and part of it is having Payload baked in. This is the setup I came up with (with help from Claude), but it seems to messy/over complicated. Can I get some quick feedback on this approach and if you have suggestions, I'd love to hear them!

I'm still working on the revalidation hook setup so when a user clicks save, it triggers a re-deploy so the site is always statically generated and fast.

// Enable ISR with on-demand revalidation for performance
export const revalidate = 3600; // Cache for 1 hour, revalidate on-demand via webhook

export default async function Home() {
  // Try to fetch from CMS, fall back to static data if database is unavailable
  let heroData: any;
  let aboutData: any;
  let projects: any;

  // Check if we're in draft mode for live preview
  const { isEnabled: isDraftMode } = await draftMode();

  try {
    const payload = await getPayload({ config });

    // Fetch all CMS data in parallel for better performance
    [heroData, aboutData, processData, projectsSection, contactSection, companyInfo, services, projects, testimonials] = await Promise.all([
      payload.findGlobal({ slug: "hero-section", draft: isDraftMode }),
      payload.findGlobal({ slug: "about-section", draft: isDraftMode }),
      payload.find({
        collection: "projects",
        where: { featured: { equals: true } },
        limit: 6,
        draft: isDraftMode,
      }),
    ]);
  } catch (error) {
    // Use fallback data when CMS is unavailable (e.g., during build without database)
    console.warn("CMS unavailable, using fallback data:", error);
    heroData = fallbackHeroData;
    aboutData = fallbackAboutData;
    projects = { docs: fallbackProjects };
  }

  // Extract background image URL if it's a Media object
  const backgroundImage =
    typeof heroData.backgroundImage === "object" && heroData.backgroundImage !== null
      ? (heroData.backgroundImage as any).url
      : heroData.backgroundImage;

  return (
    <main className="min-h-screen">
      {/* Hero Section - Data from CMS */}
      <Hero
        title={heroData.title as string}
        subtitle={heroData.subtitle as string}
        description={heroData.description as string}
        primaryCTA={heroData.primaryCTA as any}
        secondaryCTA={heroData.secondaryCTA as any}
        backgroundImage={backgroundImage}
        backgroundVideo={heroData.backgroundVideo as string}
        overlay={heroData.overlay as boolean}
        overlayOpacity={heroData.overlayOpacity as number}
      />

      {/* About Section - Data from CMS */}
      <AboutSection data={aboutData as AboutSectionData} />

      {/* Featured Projects Section - Data from CMS */}
      <FeaturedProjectsSection
        data={projects.docs as Project[]}
        title={projectsSection?.title}
      />

    </main>
  );
}
true sigil
fresh agate
#

@true sigil I'll take a look at it! Thank you so much

In general, does that structure look reasonable? I'm not against using ai, but I do want to make sure that I am understanding what's going on and what's best practices

true sigil
#

Not really, but how I would use the skill is to ask it what Payload best practices are and make recommendations and (the key part) tell me why. Some examples, I wouldn’t use global for sections, that’s what blocks are for. Payload is entirely type safe, so most, if not all any types are unnecessary and should be a more specific type. I’m not sure I’ve ever seen that Promise.all pattern for any Payload project, but that doesn’t mean it’s inherently bad. The fallback is wise, though. backgroundImage as any should be cast as your media collection instead.

#

If you look at the website template, you’ll see some great best practices with working code. I always start with the blank template but use the website template as a reference.