Home App Docs Blog Github

How to get header and footer using next js

Hey,

I have a custom Shopify solution and I’m using Builder.io for static content like the home page with Next JS.

I used my custom react components only and I want to have a header and footer for other dynamic pages like product and collection.

I converted the header and footer to a symbol from the home page model content. and I managed to edit the symbol but when I want to render it on the page, I got nothing but when I add a simple text. I got it. the issue is with my custom react component doesn’t render on other pages but it does work on the home page.

// pages/edit-builder-symbol.tsx
import "../components/navigation";
import "../components/footer"
import { BuilderComponent, Builder, builder } from '@builder.io/react'

export default function EditBuilderSymbol() {
  return <BuilderComponent model="symbols" />
}

// pages/product/[product].tsx
import { getProductSlugs, getProduct } from '@lib/shopify'
import getCompany from '@lib/company'
import BuilderConfig from '@config/builder'
import { BuilderComponent, builder } from '@builder.io/react'
import { useRouter } from 'next/router'

import { useState, useEffect } from 'react'
import { Disclosure, RadioGroup, Tab } from '@headlessui/react'
import { StarIcon } from '@heroicons/react/solid'
import { HeartIcon, MinusSmIcon, PlusSmIcon } from '@heroicons/react/outline'
import { CartState, Checkout } from '@lib/useCart'

const BUILDER_API_KEY = 'adbba6bbdfab45c485e182cb63321c25'
builder.init(BUILDER_API_KEY)



export async function getStaticPaths() {
  const productSlugs = await getProductSlugs()

  const paths = productSlugs.map((slug) => {
    const product = String(slug.node.handle)
    return {
      params: { product },
    }
  })

  return {
    paths,
    fallback: false,
  }
}

export async function getStaticProps({ params }) {
  const productData = await getProduct(params.product)
  const content = await builder.get('symbols').promise()

  console.log(content)

  return {
    props: {
      productData,
      content,
    },
  }
}

const ProductPage = ({ productData, content }) => {

 
  return (
    <div className="bg-white">

      {content && (
        <BuilderComponent
          content={content}
          model="symbols"
        />
      )}
    </div>
  )
}
export default ProductPage

Hey Ilias, given that the issue involves custom components, it’s challenging for me to really suggest anything concrete because I don’t have access to the full breadth of the code that might be involved. I understand that you might not be able to share all of your code but if you could produce a code-sandbox that demonstrates at least the core of your issue it’d be a lot easier to help.

I have a template here that you can modify to demonstrate the issue, just swap out the builder API key for your own and make what ever other changes are required to try and render the symbols.

PS: I don’t understand the relevance of EditBuilderSymbol in your example above, it doesn’t looks like it’s referred to in the other example.

I think there may be some confusion about what symbols are used for - custom components largely fill the same role, you would use a symbol if you wanted to create a reusable template that’s managed within builder, where as a custom component would be a reusable template that’s managed in your own codebase.

Thank you for your quick reply. here’s the sandbox and screenshots to know more about the issue


In the end result, I would like to get the header and footer from the home page and render it to other pages that I’ll not use builder.io editor

Okay so as I understand it, you want to have pages that are controlled in code, and would like the render the header and footer within these pages, and have the header and footer be content that’s managed by builder - is that correct?

If that’s the case we have some documentations about this specific use-case here under the section “Section Models”.

For your example, rather than using a single “symbols” model to manage your headers and footers, try creating two separate models, “header”, and “footer” to manage this content.

In your react code you’d include a BuilderComponent for each model sandwiched around your content:

import { builder, BuilderComponent } from "@builder.io/react";

builder.init("YJIGb4i01jvw0SRdL5Bt");

export default function IndexPage() {
  return (
    <div>
      <BuilderComponent model="header" />
      Here's some content that's managed in next.js
      <BuilderComponent model="footer" />
    </div>
  );
}

Okay, Great.

I would like to bring my own React component for the header and footer. Add ability to add them to the home page (builder.io page).

I’ll add header and footer model but I want to add my own react components to it.

(post deleted by author)

To add custom “header” and “footer” components you can use custom components.

You would register your header and footer components like:

import * as React from "react";
import { Builder } from "@builder.io/react";

export const Header = (props) => (
  <div>{"..."}</div>
);

Builder.registerComponent(Header, {
  name: "Header",
});

export const Footer = (props) => (
  <div>{"..."}</div>
);

Builder.registerComponent(Footer, {
  name: "Footer",
});

And then just make sure that this file is imported for the side-effect of registering with builder to occur (as explained in that linked documentation).

Your components should then be available in the insert menu if they were registered correctly like in gif here:
If things aren’t working I would check the console for errors and verify that the code where you’re calling Builder.registerComponent is being called.

it’s already registred but doesn’t show up in the header and footer model and show only in page model

If you update the code sandbox example or provide a new one I can take a look.

I create a header and footer model. I added a new entry but I would like to use my own React components like on the page model.

Home Page
Footer Entry

@Dylan I would like to make reusable header and footer with my own react components and I need it very urgent

Hey Ilias, you’ll have to provide a code sandbox example demonstrating the issue otherwise I can only guess.

If you’re using a custom component you do not need to create a model for the header or footer.

Only create the header and footer models if you’d like to manage that content in builder.

Here is an example where I’m providing my own custom header component:

import Link from "next/link";

import { builder, Builder, BuilderComponent } from "@builder.io/react";

builder.init("YJIGb4i01jvw0SRdL5Bt");

const Header = () => {
  return <div>{"This is a custom header"}</div>;
};

Builder.registerComponent(Header, {
  name: "Custom Header"
});

export default function IndexPage() {
  return (
    <div>
      Hello World.{" "}
      <Link href="/about">
        <a>About</a>
      </Link>
      <BuilderComponent model="page" url="/" />
    </div>
  );
}

This is in codesandbox, I copy and paste the preview link into builder:

I set the preview url in builder, and I can see that my custom component is available on the left.

Dropping the layer in I can see the text I set from react.

Thank you @Dylan. I managed to get this fixed by importing my custom react components where I render builder component in product page

1 Like