Skip to main content
Os widgets Martan são Web Components padrão e podem ser usados diretamente em qualquer framework moderno.

React

1. Configuração Inicial

Primeiro, carregue o script dos widgets no seu index.html ou _document.tsx (Next.js):
<!-- public/index.html ou pages/_document.tsx -->
<script>
  window.MartanConfig = window.MartanConfig || {}
  window.MartanConfig.init({
    storeId: 'seu-store-id',
    storeKey: 'sua-store-key'
  })
</script>
<script type="module" src="https://cdn.martan.app/widgets.js"></script>

2. Declarar Tipos TypeScript (opcional)

Crie um arquivo martan-widgets.d.ts para tipagem:
// src/types/martan-widgets.d.ts
declare namespace JSX {
  interface IntrinsicElements {
    'martan-rating': React.DetailedHTMLProps<
      React.HTMLAttributes<HTMLElement> & {
        'data-store-id'?: string
        'data-store-key'?: string
        'data-product-id'?: string
        'data-product-sku'?: string
        'data-star-color'?: string
        'data-theme'?: string
        'data-disable-auto-fetch'?: boolean
        rating?: number
        'total-reviews'?: number
      },
      HTMLElement
    >
    'martan-reviews': React.DetailedHTMLProps<
      React.HTMLAttributes<HTMLElement> & {
        'data-store-id'?: string
        'data-store-key'?: string
        'data-product-id'?: string
        'data-product-sku'?: string
        'data-items-per-page'?: number
        'data-header-type'?: string
        'data-list-type'?: string
      },
      HTMLElement
    >
    'martan-questions': React.DetailedHTMLProps<
      React.HTMLAttributes<HTMLElement> & {
        'data-store-id'?: string
        'data-store-key'?: string
        'data-product-id'?: string
        'data-product-sku'?: string
        'data-enable-new-questions'?: boolean
      },
      HTMLElement
    >
  }
}

3. Componentes React

// components/ProductRating.tsx
import React from 'react'

interface ProductRatingProps {
  productSku: string
  productId?: string
  starColor?: string
  theme?: 'compact' | null
}

export const ProductRating: React.FC<ProductRatingProps> = ({
  productSku,
  productId,
  starColor,
  theme
}) => {
  return (
    <martan-rating
      data-product-sku={productSku}
      data-product-id={productId}
      data-star-color={starColor}
      data-theme={theme || undefined}
    />
  )
}
// components/ProductReviews.tsx
import React from 'react'

interface ProductReviewsProps {
  productSku: string
  productId?: string
  itemsPerPage?: number
  headerType?: 'default' | 'histogram' | 'compact' | 'minimal' | 'centered'
  listType?: 'grid' | 'list'
}

export const ProductReviews: React.FC<ProductReviewsProps> = ({
  productSku,
  productId,
  itemsPerPage = 10,
  headerType = 'default',
  listType = 'grid'
}) => {
  return (
    <martan-reviews
      data-product-sku={productSku}
      data-product-id={productId}
      data-items-per-page={itemsPerPage}
      data-header-type={headerType}
      data-list-type={listType}
    />
  )
}
// components/ProductQuestions.tsx
import React from 'react'

interface ProductQuestionsProps {
  productSku: string
  productId?: string
  enableNewQuestions?: boolean
}

export const ProductQuestions: React.FC<ProductQuestionsProps> = ({
  productSku,
  productId,
  enableNewQuestions = true
}) => {
  return (
    <martan-questions
      data-product-sku={productSku}
      data-product-id={productId}
      data-enable-new-questions={enableNewQuestions}
    />
  )
}

4. Uso em uma Página

// pages/ProductPage.tsx
import React from 'react'
import { ProductRating } from '../components/ProductRating'
import { ProductReviews } from '../components/ProductReviews'
import { ProductQuestions } from '../components/ProductQuestions'

const ProductPage: React.FC<{ productSku: string }> = ({ productSku }) => {
  return (
    <div>
      <h1>Produto</h1>

      <ProductRating
        productSku={productSku}
        starColor="#fbbf24"
      />

      <ProductReviews
        productSku={productSku}
        headerType="default"
        listType="grid"
      />

      <ProductQuestions
        productSku={productSku}
        enableNewQuestions={true}
      />
    </div>
  )
}

export default ProductPage

SSR (Server-Side Rendering)

Os widgets são client-side only. Em Next.js, use dynamic import:
// Next.js
import dynamic from 'next/dynamic'

const ProductRating = dynamic(
  () => import('../components/ProductRating'),
  { ssr: false }
)

Vue

1. Configuração Inicial

No seu index.html ou nuxt.config.ts (Nuxt.js):
<!-- public/index.html -->
<script>
  window.MartanConfig = window.MartanConfig || {}
  window.MartanConfig.init({
    storeId: 'seu-store-id',
    storeKey: 'sua-store-key'
  })
</script>
<script type="module" src="https://cdn.martan.app/widgets.js"></script>

2. Componentes Vue

<!-- components/ProductRating.vue -->
<template>
  <martan-rating
    :data-product-sku="productSku"
    :data-product-id="productId"
    :data-star-color="starColor"
    :data-theme="theme"
  />
</template>

<script setup lang="ts">
interface Props {
  productSku: string
  productId?: string
  starColor?: string
  theme?: 'compact' | null
}

withDefaults(defineProps<Props>(), {
  starColor: '#ffc107',
  theme: null
})
</script>
<!-- components/ProductReviews.vue -->
<template>
  <martan-reviews
    :data-product-sku="productSku"
    :data-product-id="productId"
    :data-items-per-page="itemsPerPage"
    :data-header-type="headerType"
    :data-list-type="listType"
  />
</template>

<script setup lang="ts">
interface Props {
  productSku: string
  productId?: string
  itemsPerPage?: number
  headerType?: 'default' | 'histogram' | 'compact' | 'minimal' | 'centered'
  listType?: 'grid' | 'list'
}

withDefaults(defineProps<Props>(), {
  itemsPerPage: 10,
  headerType: 'default',
  listType: 'grid'
})
</script>
<!-- components/ProductQuestions.vue -->
<template>
  <martan-questions
    :data-product-sku="productSku"
    :data-product-id="productId"
    :data-enable-new-questions="enableNewQuestions"
  />
</template>

<script setup lang="ts">
interface Props {
  productSku: string
  productId?: string
  enableNewQuestions?: boolean
}

withDefaults(defineProps<Props>(), {
  enableNewQuestions: true
})
</script>

3. Uso em uma Página

<!-- pages/ProductPage.vue -->
<template>
  <div>
    <h1>Produto</h1>

    <ProductRating
      :product-sku="productSku"
      star-color="#fbbf24"
    />

    <ProductReviews
      :product-sku="productSku"
      header-type="default"
      list-type="grid"
    />

    <ProductQuestions
      :product-sku="productSku"
      :enable-new-questions="true"
    />
  </div>
</template>

<script setup lang="ts">
import ProductRating from '@/components/ProductRating.vue'
import ProductReviews from '@/components/ProductReviews.vue'
import ProductQuestions from '@/components/ProductQuestions.vue'

const route = useRoute()
const productSku = computed(() => route.params.sku as string)
</script>

4. Nuxt.js - Configuração Global

Para Nuxt.js, você pode adicionar o script no nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      scripts: [
        {
          innerHTML: `
            window.MartanConfig = window.MartanConfig || {}
            window.MartanConfig.init({
              storeId: 'seu-store-id',
              storeKey: 'sua-store-key'
            })
          `,
          type: 'text/javascript'
        },
        {
          src: 'https://cdn.martan.app/widgets.js',
          type: 'module'
        }
      ]
    }
  }
})

SSR (Server-Side Rendering)

Em Nuxt.js, use ClientOnly wrapper:
<!-- Nuxt.js -->
<template>
  <ClientOnly>
    <ProductRating :product-sku="productSku" />
  </ClientOnly>
</template>

Notas Importantes

  1. Atributos com hífen: Em React, use data-product-sku (com hífen) ou dataProductSku (camelCase). Em Vue, use :data-product-sku ou data-product-sku.
  2. Configuração Global: Configure window.MartanConfig antes de carregar os widgets para evitar repetir credenciais.
  3. TypeScript: Os tipos são opcionais, mas recomendados para melhor experiência de desenvolvimento.
  4. SSR (Server-Side Rendering): Os widgets são client-side only. Use dynamic import (Next.js) ou ClientOnly wrapper (Nuxt.js).