ComponentsThinking Ads

Thinking Ads

Show ads during AI loading states to monetize waiting time.

Basic Usage

import { useDisplayAd } from '@earnlayer/sdk/react';
 
function ThinkingAdComponent() {
  const { ad, isLoading, refetchWithRefresh } = useDisplayAd({ 
    adType: 'thinking',
    autoFetch: true
  });
 
  if (isLoading || !ad) return null;
 
  return (
    <a 
      href={ad.url}
      target="_blank"
      rel="noopener noreferrer"
      className="inline-flex items-center gap-2 text-sm text-blue-600"
    >
      <span className="animate-pulse"></span>
      {ad.title}
    </a>
  );
}

Integration with Chat

Use thinking ads when the AI is processing:

function ChatComponent() {
  const [isThinking, setIsThinking] = useState(false);
 
  const handleSendMessage = async (message: string) => {
    setIsThinking(true);
    
    const response = await fetch('/api/chat', {
      method: 'POST',
      body: JSON.stringify({ message })
    });
    
    setIsThinking(false);
    // Handle response...
  };
 
  return (
    <div>
      {/* Messages */}
      
      {/* Thinking indicator with ad */}
      {isThinking && (
        <div className="flex items-center gap-2">
          <span>Thinking...</span>
          <ThinkingAdComponent />
        </div>
      )}
      
      {/* Input */}
    </div>
  );
}

Auto-Refresh Thinking Ads

Thinking ads can automatically refresh while the AI is processing:

function AutoRefreshThinkingAd() {
  const { ad, isLoading, refetchWithRefresh } = useDisplayAd({
    adType: 'thinking',
    autoFetch: true,
    thinkingAdTimeout: 4
  });
 
  // Auto-refresh every 5 seconds while ad is visible
  useEffect(() => {
    if (!ad || isLoading) return;
 
    const timer = setTimeout(() => {
      refetchWithRefresh();
    }, 5000); // 5 seconds
 
    return () => clearTimeout(timer);
  }, [ad?.id, isLoading, refetchWithRefresh]);
 
  if (isLoading || !ad) return null;
 
  return (
    <a 
      href={ad.url}
      target="_blank"
      rel="noopener noreferrer"
      className="inline-flex items-center gap-2 text-sm text-blue-600"
    >
      <span className="animate-pulse"></span>
      {ad.title}
    </a>
  );
}

Note: Thinking ads typically disappear when AI response completes, so auto-refresh is most useful for longer processing times or when you want to show multiple ads during extended thinking states.

Key Points

Manual Fetch Control For production use, set autoFetch: false and manually refetch when status becomes “submitted” to ensure ads appear for every message. See Advanced Implementation below.

Minimum Display Duration To prevent ads from disappearing too quickly when AI responses are fast, implement a minimum display duration. See Advanced Implementation below.

Non-Intrusive Ads appear inline with loading indicator, minimal disruption.

Monetize Wait Time Turn loading states into revenue opportunities.

Styling Examples

Inline with Loading Spinner

{isThinking && (
  <div className="flex items-center gap-3 p-3 bg-gray-50 rounded">
    <div className="animate-spin h-4 w-4 border-2 border-blue-500 border-t-transparent rounded-full" />
    <span className="text-gray-600">Thinking...</span>
    <ThinkingAdComponent />
  </div>
)}

With Ellipsis Animation

{isThinking && (
  <div className="flex items-center gap-2 text-gray-600">
    <span>Generating response</span>
    <span className="animate-bounce">.</span>
    <span className="animate-bounce animation-delay-100">.</span>
    <span className="animate-bounce animation-delay-200">.</span>
    <ThinkingAdComponent />
  </div>
)}

Advanced Implementation

For production-ready thinking ads that appear consistently and remain visible for a minimum duration, see the Advanced Display Ad Implementation guide.

Next Steps