Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Contentful Bundle Laravel Package

contentful/contentful-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require contentful/contentful-bundle
    

    Add the bundle to config/bundles.php:

    Contentful\ContentfulBundle\ContentfulBundle::class => ['dev' => true],
    
  2. Basic Configuration Create config/packages/contentful.yaml:

    contentful:
        delivery:
            space_id: 'your-space-id'
            access_token: 'your-delivery-token'
            environment_id: 'your-environment-id'  # Optional (defaults to 'master')
    
  3. First Use Case: Fetching Content Inject the ContentfulClient service in a controller or service:

    use Contentful\ContentfulBundle\Client\ContentfulClientInterface;
    
    public function __construct(private ContentfulClientInterface $client) {}
    
    public function showBlogPost(ContentTypeIdentifier $id) {
        $entry = $this->client->getEntry($id);
        return $this->render('blog/post.html.twig', ['entry' => $entry]);
    }
    
  4. Twig Integration Enable Twig extensions in config/packages/twig.yaml:

    twig:
        globals:
            contentful: '@contentful.twig.contentful_extension'
    

    Use in templates:

    {{ contentful.entry('blogPostId')|raw }}
    

Implementation Patterns

Common Workflows

  1. Fetching Entries

    // Single entry
    $entry = $client->getEntry('blogPostId');
    
    // Multiple entries (query)
    $query = $client->createQuery()
        ->where('fields.title', 'LIKE', '%Laravel%')
        ->limit(10);
    $entries = $client->getEntries($query);
    
  2. Content Types & Fields

    $contentType = $client->getContentType('blogPost');
    $fields = $contentType->getFields(); // Array of field definitions
    
  3. Localization

    contentful:
        delivery:
            locales: ['en-US', 'es-ES']  # Optional
    
    $entry = $client->getEntry($id, 'es-ES'); // Fetch localized entry
    
  4. Caching (Symfony Cache Component)

    contentful:
        delivery:
            cache:
                enabled: true
                pool: 'cache.app'  # Symfony cache pool
                ttl: 3600           # Cache TTL in seconds
    
  5. Event Listeners (Real-Time Updates)

    // config/services.yaml
    services:
        App\EventListener\ContentfulWebhookListener:
            tags:
                - { name: 'kernel.event_listener', event: 'contentful.webhook', method: 'onWebhook' }
    

Integration Tips

  • Laravel-Specific: Use Symfony’s HttpClient or Laravel’s Http facade via dependency injection.
  • Doctrine ORM: Map Contentful entries to Doctrine entities using Contentful\ContentfulBundle\Doctrine\ContentfulEntityListener.
  • API Platform: Combine with api-platform/core for GraphQL/REST endpoints:
    # config/packages/api_platform.yaml
    api_platform:
        formats:
            jsonld:
                contentful: ['application/vnd.api+json']
    

Gotchas and Tips

Pitfalls

  1. Token Security

    • Never commit access_token to version control. Use environment variables or Symfony’s parameter_bag:
      # .env
      CONTENTFUL_ACCESS_TOKEN=your-token-here
      
      # config/packages/contentful.yaml
      contentful:
          delivery:
              access_token: '%env(CONTENTFUL_ACCESS_TOKEN)%'
      
  2. Rate Limiting

    • Contentful enforces rate limits. Cache aggressively or implement retries:
      $client->setRetryOptions(['max_retries' => 3]);
      
  3. Field Serialization

    • Rich text (richText) and asset fields (asset) return nested objects. Flatten them in a DTO or use Twig filters:
      {{ entry.fields.body|contentful_richtext_to_html }}
      
  4. Environment Sync

    • The bundle defaults to master environment. Explicitly set environment_id to avoid surprises:
      contentful:
          delivery:
              environment_id: 'staging'  # Not 'master'
      

Debugging

  • Enable Debug Mode

    contentful:
        delivery:
            debug: true  # Logs all API requests/responses
    

    Check logs in var/log/dev.log.

  • Validate Responses Use Contentful\ContentfulBundle\Exception\ContentfulException to catch API errors:

    try {
        $entry = $client->getEntry($id);
    } catch (ContentfulException $e) {
        // Handle 404, 403, etc.
        $this->addFlash('error', $e->getMessage());
    }
    

Extension Points

  1. Custom Field Resolvers Extend Contentful\ContentfulBundle\Resolver\FieldResolverInterface to handle custom field types:

    class CustomFieldResolver implements FieldResolverInterface {
        public function resolve($value, Field $field) {
            return json_decode($value, true); // Example: JSON field
        }
    }
    

    Register in services.yaml:

    services:
        App\Resolver\CustomFieldResolver:
            tags:
                - { name: 'contentful.field_resolver', alias: 'customField' }
    
  2. Override Client Configuration Dynamically configure the client via a compiler pass:

    use Contentful\ContentfulBundle\DependencyInjection\Compiler\ContentfulCompilerPass;
    
    public function process(ContainerBuilder $container) {
        $container->addCompilerPass(new ContentfulCompilerPass());
    }
    
  3. Webhook Validation Validate Contentful webhooks in a listener:

    public function onWebhook(WebhookEvent $event) {
        $payload = $event->getPayload();
        if (!$this->validateWebhookSignature($payload)) {
            throw new \RuntimeException('Invalid webhook signature');
        }
    }
    

Performance Tips

  • Batch Loading Use include in queries to fetch linked entries in one request:

    $query->include(['author', 'tags']);
    
  • Lazy Loading For large datasets, implement pagination:

    $query->limit(10)->skip(0); // Page 1
    $query->limit(10)->skip(10); // Page 2
    
  • Symfony Cache Adapter Configure Redis/Memcached for distributed caching:

    contentful:
        delivery:
            cache:
                pool: 'cache.redis'  # Use Redis cache pool
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle