Skip to content
WeaversePublic

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

2 watching

Forks

Latest commit

Β 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Sonic - Shopify Hydrogen Theme

πŸ“š Read the docs | πŸ—£ Join our community on Slack | 🐞 Report a bug

Weaverse + Hydrogen + Shopify

Sonic is a Shopify Hydrogen theme built with Weaverse, Sonic delivers authentic, cutting-edge design tailored for tech enthusiasts, empowering seamless online stores for electronics and gadgets.

Demo

What's included

  • Remix
  • Hydrogen
  • Oxygen
  • Shopify CLI
  • Biome (Eslint, Prettier alternative)
  • GraphQL generator
  • TypeScript and JavaScript flavors
  • Tailwind CSS (via PostCSS)
  • Radix UI
  • New Shopify customer account API
  • Full-featured setup of components and routes
  • Fully customizable inside Weaverse Studio

Deployment

Getting started

Requirements:

  • Node.js version 18.0.0 or higher

Follow these steps to get started with Sonic and begin crafting your Hydrogen-driven storefront:

  1. Install Weaverse Hydrogen Customizer from Shopify App Store.
  2. Create new Hydrogen storefront inside Weaverse.
  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 and tailoring your storefront according to your preferences.

Features overview

Fetching page data inside route's loader

Fetching page data inside route's loader is a common pattern in Hydrogen. Weaverse provides a convenient way to do that by using context.weaverse.loadPage function.

import { defer } from '@shopify/remix-oxygen';
import { type RouteLoaderArgs } from '@weaverse/hydrogen';

export async function loader(args: RouteLoaderArgs) {
  let {params, context} = args;

  return defer({
    weaverseData: await context.weaverse.loadPage({type: 'INDEX'}),
    // More route's loader data...
  });
}

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 section/component

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

import type {
  HydrogenComponentProps,
  HydrogenComponentSchema,
} from '@weaverse/hydrogen';
import { forwardRef } from 'react';

interface VideoProps extends HydrogenComponentProps {
  heading: string;
  description: string;
  videoUrl: string;
}

let Video = forwardRef<HTMLElement, VideoProps>((props, ref) => {
  let {heading, description, videoUrl, ...rest} = props;
  return (
    <section ref={ref} {...rest}>
      <div className="py-8 px-4 mx-auto max-w-screen-xl lg:px-12 sm:text-center lg:py-16">
        <h2 className="mb-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white">
          {heading}
        </h2>
        <p className="font-light text-gray-500 sm:text-lg md:px-20 lg:px-38 xl:px-48 dark:text-gray-400">
          {description}
        </p>
        <iframe
          className="mx-auto mt-8 w-full max-w-2xl h-64 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 let schema: HydrogenComponentSchema = {
  type: 'video',
  title: 'Video',
  inspector: [
    {
      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 let loader = async ({weaverse, data}: ComponentLoaderArgs) => {
  let {data} = await weaverse.storefront.query<SeoCollectionContentQuery>(
    HOMEPAGE_SEO_QUERY,
    {
      variables: {handle: data.collection.handle || 'frontpage'},
    },
  );
  return data;
};

And then you can use the data in your component with Component.props.loaderData πŸ€—

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.

Weaverse Studio

Local development inspects

References

License

This project is provided under the MIT License.


Let Weaverse & Sonic empower your Shopify store with top-notch performance and unmatched customization possibilities! πŸš€

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages