Menu is a navigation component with one level of submenus.
<h:form>
    <p:growl id="messages" showDetail="true"/>
    <div class="card">
        <h5>Inline</h5>
        <p:menu>
            <p:submenu label="Options">
                <p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
                            icon="pi pi-save"/>
                <p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
                <p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
            </p:submenu>
            <p:submenu label="Navigations">
                <p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
                <p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
                <p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
                <p:menuitem value="Logout (disabled)" icon="pi pi-power-off" disabled="true"/>
            </p:submenu>
        </p:menu>
    </div>
    <div class="card">
        <h5>Overlay</h5>
        <p:commandButton id="dynaButton" value="Show" type="button" icon="pi pi-bars"/>
        <p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom">
            <p:submenu label="Options">
                <p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
                            icon="pi pi-save"/>
                <p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
                <p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
            </p:submenu>
            <p:submenu label="Navigations">
                <p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
                <p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
                <p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
                <p:menuitem value="Logout (disabled)" icon="pi pi-power-off" disabled="true"/>
            </p:submenu>
        </p:menu>
    </div>
    <div class="card">
        <h5>Programmatic</h5>
        <p:menu model="#{menuView.model}" toggleable="true" />
    </div>
    <div class="card">
        <h5>Toggleable</h5>
        <p:menu toggleable="true">
            <p:submenu label="Options">
                <p:menuitem value="Save (Non-Ajax)" action="#{menuView.save}" update="messages" ajax="false"
                            icon="pi pi-save"/>
                <p:menuitem value="Update" action="#{menuView.update}" update="messages" icon="pi pi-refresh"/>
                <p:menuitem value="Delete" action="#{menuView.delete}" update="messages" icon="pi pi-times"/>
            </p:submenu>
            <p:submenu label="Navigations">
                <p:menuitem value="Website" url="http://www.primefaces.org" icon="pi pi-external-link"/>
                <p:menuitem value="Internal" outcome="/ui/menu/menubar" icon="pi pi-upload"/>
                <p:menuitem value="Update (right click open in new tab)" action="#{menuView.update}" update="messages" url="http://www.primefaces.org" icon="pi pi-thumbs-up"/>
            </p:submenu>
        </p:menu>
    </div>
</h:form>
package org.primefaces.showcase.view.menu;
import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultMenuModel;
import org.primefaces.model.menu.DefaultSubMenu;
import org.primefaces.model.menu.MenuModel;
import java.io.IOException;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class MenuView implements Serializable {
    private static final long serialVersionUID = 1L;
    private MenuModel model;
    @PostConstruct
    public void init() {
        model = new DefaultMenuModel();
        //First submenu
        DefaultSubMenu firstSubmenu = DefaultSubMenu.builder()
                .label("Options")
                .expanded(true)
                .build();
        DefaultMenuItem item = DefaultMenuItem.builder()
                .value("Save (Non-Ajax)")
                .icon("pi pi-save")
                .ajax(false)
                .command("#{menuView.save}")
                .update("messages")
                .build();
        firstSubmenu.getElements().add(item);
        item = DefaultMenuItem.builder()
                .value("Update")
                .icon("pi pi-refresh")
                .command("#{menuView.update}")
                .update("messages")
                .build();
        firstSubmenu.getElements().add(item);
        item = DefaultMenuItem.builder()
                .value("Delete")
                .icon("pi pi-times")
                .command("#{menuView.delete}")
                .update("messages")
                .build();
        firstSubmenu.getElements().add(item);
        model.getElements().add(firstSubmenu);
        //Second submenu
        DefaultSubMenu secondSubmenu = DefaultSubMenu.builder()
                .label("Navigations")
                .expanded(false)
                .build();
        item = DefaultMenuItem.builder()
                .value("Website")
                .url("http://www.primefaces.org")
                .icon("pi pi-external-link")
                .build();
        secondSubmenu.getElements().add(item);
        item = DefaultMenuItem.builder()
                .value("Internal")
                .icon("pi pi-upload")
                .command("#{menuView.redirect}")
                .build();
        secondSubmenu.getElements().add(item);
        model.getElements().add(secondSubmenu);
    }
    public MenuModel getModel() {
        return model;
    }
    public void redirect() throws IOException {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.redirect(ec.getRequestContextPath());
    }
    public void save() {
        addMessage("Save", "Data saved");
    }
    public void update() {
        addMessage("Update", "Data updated");
    }
    public void delete() {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Delete", "Data deleted");
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
    public void sleepAndSave() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
        save();
    }
    public void sleepAndUpdate() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
        update();
    }
    public void sleepAndDelete() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
        delete();
    }
    public void addMessage(String summary, String detail) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
}