Logo

Aspen

v1.0.0-Aug 15, 2025
Free

A premium furniture theme designed for home decor stores with advanced Shopify Plus features and seamless shopping experience

Includes support for:
  • Shopify Plus combined listings
  • Quick shop drawer
  • Mega menu navigation
  • Predictive search
  • Stock counter
  • Product recommendations
Aspen
Shopify Plus Combined Listings

Shopify Plus Combined Listings

Advanced Shopify Plus feature support with combined product listings for better inventory management and customer experience.

Quick Shop Drawer

Quick Shop Drawer

Seamless shopping experience with quick shop functionality in a slide-out drawer, allowing customers to add items without leaving the page.

Advanced Navigation & Search

Advanced Navigation & Search

Enhanced user experience with mega menu navigation and predictive search functionality for effortless product discovery.

Aspen - Shopify Hydrogen Theme

Aspen is a sophisticated Shopify theme crafted specifically for home furniture and interior design stores. Powered by Hydrogen, React Router, and Weaverse, this theme delivers lightning-fast storefronts with exceptional performance and elegant design aesthetics perfect for showcasing furniture collections, home decor, and interior design services.

Demo

aspen.weaverse.dev

What's included

Weaverse + Hydrogen + Shopify

  • React Router v7
  • Hydrogen 2025.5.0
  • Oxygen
  • Shopify CLI
  • Biome (ESLint, Prettier alternative)
  • GraphQL generator
  • TypeScript and JavaScript flavors
  • Tailwind CSS v4 (via Vite)
  • Radix UI components
  • New Shopify customer account API
  • Full-featured setup of components and routes
  • Furniture-specific sections and layouts
  • Fully customizable inside Weaverse Studio

Deployment

Getting started

Requirements:

  • Node.js version 20.0.0 or higher
  • npm or pnpm package manager

Follow these steps to get started with Aspen and begin crafting your furniture store:

  1. Install Weaverse Hydrogen Customizer from Shopify App Store.
  2. Create new Hydrogen storefront inside Weaverse and select the Aspen theme.
  3. Initialize the project and start a local dev server with @weaverse/cli tool as instructed in the Weaverse Studio. Create new Weaverse Shopify Hydrogen project
  4. Open Weaverse Studio to start customizing your furniture store with specialized sections for product showcases, room inspirations, and interior design content.

Quick Start Commands

# Install dependenciesnpm install
# Start development server on port 3456npm run dev
# Run code quality checks before committingnpm run biome:fixnpm run typecheck
# Build for productionnpm run build
# Run E2E testsnpm run e2e

Features overview

Fetching page data with parallel loading

Pilot uses parallel data loading for optimal performance. Every route loads Weaverse data alongside GraphQL queries using Promise.all():

import { data } from '@shopify/remix-oxygen';import { type LoaderFunctionArgs } from '@shopify/remix-oxygen';
export async function loader({ context }: LoaderFunctionArgs) {  const { storefront, weaverse } = context;
  // Parallel data loading for best performance  const [collections, weaverseData] = await Promise.all([    storefront.query(COLLECTIONS_QUERY),    weaverse.loadPage({ type: 'INDEX' }),  ]);
  return data({    collections,    weaverseData,  });}

weaverse is an WeaverseClient instance that has been injected into the app context by Weaverse. It provides a set of methods to interact with the Weaverse API.

// app/lib/context.ts
const hydrogenContext = createHydrogenContext({    env,    request,    cache,    waitUntil,    session,    i18n: getLocaleFromRequest(request),    cart: {      queryFragment: CART_QUERY_FRAGMENT,    },  });
  return {    ...hydrogenContext,    // declare additional Remix loader context    weaverse: new WeaverseClient({      ...hydrogenContext,      request,      cache,      themeSchema,      components,    }),  };

Rendering page content

Weaverse pages is rendered using <WeaverseContent /> component.

import { WeaverseHydrogenRoot } from '@weaverse/hydrogen';import { GenericError } from '~/components/generic-error';import { components } from './components';
export function WeaverseContent() {  return (    <WeaverseHydrogenRoot      components={components}      errorComponent={GenericError}    />  );}

And in your route:

export default function Homepage() {  return <WeaverseContent />;}

Dead simple, right?

Global theme settings

Weaverse global theme settings is loaded in the root's loader with context.weaverse.loadThemeSettings function.

export async function loader({request, context}: RouteLoaderArgs) {  return defer({    // App data...    weaverseTheme: await context.weaverse.loadThemeSettings(),  });}

And then you can use it in your components with useThemeSettings hook.

import { useThemeSettings } from '@weaverse/hydrogen';
function Logo() {  let {logo} = useThemeSettings();
  return (    <div className="flex items-center">      <img src={logo} alt="Logo" />    </div>  );}

The App component is wrapped with withWeaverse HoC in order to SSR the theme settings.

import { withWeaverse } from '@weaverse/hydrogen';
function App() {  return (    <html lang={locale.language}>      // App markup    </html>  );}
export default withWeaverse(App);

Create a Weaverse section

To create a section, you need to create a new file in app/sections directory and register it in app/weaverse/components.ts file.

Important: All Weaverse sections must use forwardRef and extend HydrogenComponentProps.

import type {  HydrogenComponentProps,  createSchema,} from '@weaverse/hydrogen';import { forwardRef } from 'react';
interface VideoProps extends HydrogenComponentProps {  heading: string;  description: string;  videoUrl: string;}
const Video = forwardRef<HTMLElement, VideoProps>((props, ref) => {  const { heading, description, videoUrl, ...rest } = props;  return (    <section ref={ref} {...rest}>      <div className="mx-auto max-w-7xl px-4 py-8 lg:px-12 lg:py-16 sm:text-center">        <h2 className="mb-4 text-4xl font-extrabold tracking-tight text-gray-900">          {heading}        </h2>        <p className="font-light text-gray-500 sm:text-lg md:px-20 lg:px-38 xl:px-48">          {description}        </p>        <iframe          className="mx-auto mt-8 h-64 w-full max-w-2xl rounded-lg lg:mt-12 sm:h-96"          src={videoUrl}          title="YouTube video player"          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"          allowFullScreen        />      </div>    </section>  );});
export default Video;

Export a schema object from the file to define the component's schema with default data and settings to be used in the Weaverse Studio.

export const schema = createSchema({  type: 'video',  title: 'Video',  settings: [    {      group: 'Video',      inputs: [        {          type: 'text',          name: 'heading',          label: 'Heading',          defaultValue: 'Learn More About Our Products',          placeholder: 'Learn More About Our Products',        },        {          type: 'textarea',          name: 'description',          label: 'Description',          defaultValue: `Watch these short videos to see our products in action. Learn how to use them and what makes them special. See demos of our products being used in real-life situations. The videos provide extra details and showcase the full capabilities of what we offer. If you're interested in learning more before you buy, be sure to check out these informative product videos.`,          placeholder: 'Video description',        },        {          type: 'text',          name: 'videoUrl',          label: 'Video URL',          defaultValue: 'https://www.youtube.com/embed/-akQyQN8rYM',          placeholder: 'https://www.youtube.com/embed/-akQyQN8rYM',        },      ],    },  ],});

What if your component needs to fetch data from Shopify API or any third-party API?

Weaverse provide a powerful loader function to fetch data from any API, and it's run on the server-side 🤯😎.

Just export a loader function from your component:

import type { ComponentLoaderArgs } from '@weaverse/hydrogen';
export const loader = async ({ weaverse, data }: ComponentLoaderArgs) => {  const result = await weaverse.storefront.query<SeoCollectionContentQuery>(    HOMEPAGE_SEO_QUERY,    {      variables: { handle: data.collection.handle || 'frontpage' },    },  );  return result.data;};

And then you can use the data in your component with Component.props.loaderData 🤗

Don't forget to register your new section in app/weaverse/components.ts:

import * as Video from "~/sections/video";
export const components: HydrogenComponent[] = [  // ... existing components  Video,];

Manage content and style your pages within Weaverse Studio

Weaverse provides a convenient way to customize your theme inside the Weaverse Studio. You can add new sections, customize existing ones, and change the theme settings.

Aspen in Weaverse Studio

Project Structure

app/├── components/      # Reusable UI components│   ├── layout/     # Header, footer, navigation│   ├── product/    # Product-specific components│   └── cart/       # Cart components├── sections/       # Weaverse page builder sections├── routes/         # React Router routes (with locale prefix)├── graphql/        # GraphQL queries and fragments├── utils/          # Helper functions└── weaverse/       # Weaverse configuration
Key configuration files:- biome.json        # Code formatting and linting- codegen.ts       # GraphQL code generation- react-router.config.ts # React Router configuration- vite.config.ts   # Vite bundler configuration

Development Tools

Code Quality

Before committing, always run:

npm run biome:fix    # Fix linting/formattingnpm run typecheck    # Check TypeScript typesnpm run codegen      # Update GraphQL types

References

License

This project is provided under the MIT License.


Let Weaverse & Aspen empower your furniture store with top-notch performance, elegant design, and unmatched customization possibilities perfectly tailored for the home furniture and interior design industry! 🪑🏠

Start building sites with Weaverse themes for free

Get started