Coder Social home page Coder Social logo

btxtiger / ngx-link-preview Goto Github PK

View Code? Open in Web Editor NEW
14.0 2.0 4.0 2.52 MB

The Open Graph link preview component for Angular 6+

License: MIT License

Shell 0.48% JavaScript 8.00% TypeScript 64.90% HTML 13.34% SCSS 13.27%
angular angular-component opengraph link-preview ui library preview weblinks meta-tags metadata html-link

ngx-link-preview's Introduction

ngx-link-preview

npm npm npm

The Open Graph link preview component for Angular 6+

Installation

npm install --save ngx-link-preview

# For Angular <= 13
npm install --save [email protected]
yarn add ngx-link-preview

Features

  • Configurable preview
  • Render array of links
  • Parse links in string
  • Loading indicator
  • Theming: default and modern theme included

Requirements

  • Angular 6+
  • You will need to create an endpoint at your backend to parse an url for meta tags.
    See info below

Component configuration

1. Import to your module

@NgModule({
   imports: [
      NgxLinkPreviewModule,
      ...
   ]
})
export class AppModule { }

2. Use as regular component

<ngx-link-preview></ngx-link-preview>

3. Parameters: Configure the preview

• Two required parameters:

1. [apiRoute]="myApiRoute"

apiRoute accepts any url, where you want to retrieve the metadata from. The target url will be attached by the component as base64 urlencoded query parameter.

/** API route where to get the meta data from, component will build the full request url
 * Schema: api.example.com/api/get-meta-data?url=d3d3LmV4YW1wbGUuY29t
 */
@Input()
public apiRoute: string;
2. [getApiEndpoint$]="apiCallbackFn"

A generic callback function that returns an observable, that runs the api request on subscription. You can use the default Angular HttpClient method, or your configured backend wrapper observable.

/** Method that does the API request, provide as class member arrow function from parent */
@Input()
public getApiEndpoint$: (requestUrl: string) => Observable<any>;

For example:

public apiCallbackFn = (route: string) => {
   return this.http.get(route);
};

Optional parameters

• Links that should be rendered, default: []
/** Plain links string array */
@Input()
public links: string[] = [];
• Input string that should be parsed for links, can be combined with links[]
/** Input string to parse for links */
@Input()
public parseForLinksStr: string;
• Query parameter name, default: 'url'
/** Target url will be attached as encodeURI(btoa(url)), so it must be decoded on the server */
@Input()
public queryParamName = 'url';
• Show image in preview, default: true
/** boolean: show image in preview */
@Input()
public showImage = true;
• Show site name in preview, default: true
/** boolean: show site name in preview */
@Input()
public showSiteName = true;
• Show title in preview, default: true
/** boolean: show title in preview */
@Input()
public showTitle = true;
• Show description in preview, default: true
/** boolean: show description in preview */
@Input()
public showDescription = true;
• Show url in preview, default: false
/** boolean: show link url in preview */
@Input()
public showLinkUrl = false;
• Use cache, default: true
/** boolean: use cache to display previews faster on next rendering */
@Input()
public useCache = true;
• Max cache age in milliseconds, default: 7 days
/** number: max age the data cache of a link preview should be used */
@Input()
public maxCacheAgeMs = 1000 * 60 * 60 * 24 * 7; // 7 days
• Show loading indicator, default: true
/** boolean: show loading indicator */
@Input()
public showLoadingIndicator = true;
• HTML link <a href="..."></a> should be clickable, default: false
/**
* boolean: whether the <a href="..."></a> link should be clickable.
* This is a question of context security. Otherwise use (previewClick) event.
*/
@Input()
public useHtmlLinkDefaultClickEvent = false;
• HTML link target, default: '_blank' (new tab)
/**
* HtmlLinkTarget: where the HTML link should be opened on click.
* Only has an effect if [useHtmlLinkDefaultClickEvent]="true"
*/
@Input()
public htmlLinkTarget: HtmlLinkTarget = '_blank';
• Event emits the URL on click
/** Event emitter: on click to handle the click event, emits the clicked URL */
@Output()
public previewClicked = new EventEmitter<string>();
<!-- $event: string is URL --> 
(previewClick)="previewClicked($event)"

Theming

The package ships a default and a modern theme. The modern theme crops the preview image, what might conclude in unintended results. To use the modern theme, just pass the css class:

<ngx-link-preview class="modern"></ngx-link-preview>

Feel free to create more themes and submit a pull request or open an issue!

You can use this skeleton: (click to show)

.ngx-link-preview-container {
   .og-link-preview {
      &:hover {
      }
      .row {
         .col {
            &.preview-image {
            }
            &.text-data {
            }
            .image {
               img {
               }
            }
            .title {
            }
            .description {
            }
            .header {
               .site-name {
               }
            }
            .footer {
               .url {
               }
            }
         }
      }
   }
}

Loading spinner

You can customize the loading spinner by passing your spinner as content of the component:

<ngx-link-preview>
    <my-spinner-component></my-spinner-component>
</ngx-link-preview>

<!-- or alternatively (any child element): -->
<ngx-link-preview>
    <div class="spinner"></div>
</ngx-link-preview>

Endpoint configuration

Node.js example

With node.js you can use url-metadata

import urlMetadata from 'url-metadata';

public getMetadata(request: Request, response: Response) {
   let { url } = request.query;
   url = this.decodeSafeUrl(url);
   
   urlMetadata(url).then(
      resp => {
         response.send(resp);
      },
      error => {
         response.send(error).status(500);
      }
   );
}

public decodeSafeUrl(value: string): string {
   const valueBase64 = decodeURI(value);
   return Buffer.from(valueBase64, 'base64').toString('utf8');
}

PHP example

$router->get('/meta-tags', function() {
  $url = $_GET['url'];
  $urlDecoded = base64_decode(urldecode($url));
  ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 6.0)');
  $sites_html = file_get_contents($urlDecoded);

  $html = new DOMDocument();
  @$html->loadHTML($sites_html);

  $metaTags = [
      'title' => '',
      'description' => '',
      'image' => '',
      'canonical' => '',
      'url' => '',
      'author' => '',
      'availability' => '',
      'keywords' => '',
      'og:description' => '',
      'og:determiner' => '',
      'og:image' => '',
      'og:image:height' => '',
      'og:image:secure_url' => '',
      'og:image:type' => '',
      'og:image:width' => '',
      'og:locale' => '',
      'og:locale:alternate' => '',
      'og:site_name' => '',
      'og:title' => '',
      'og:type' => '',
      'og:url' => '',
      'price' => '',
      'priceCurrency' => '',
      'source' => '',
  ];

  foreach ($html->getElementsByTagName('meta') as $meta) {
      $property = $meta->getAttribute('property');
      $content = $meta->getAttribute('content');
      if (strpos($property, 'og') === 0) {
          $metaTags[$property] = $content;

          if ($property === 'og:title') $metaTags['title'] = $property;
          if ($property === 'og:description') $metaTags['description'] = $property;
          if ($property === 'og:image') $metaTags['image'] = $property;
      }
  }
  $metaTags['canonical'] = $urlDecoded;
  $metaTags['url'] = $urlDecoded;

  return response()->json($metaTags);
});

ngx-link-preview's People

Contributors

btxtiger avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ngx-link-preview's Issues

render link from an input

Good day !
I'm using this extension and I like it so far, I faced some issues using it such as rendering links from an input element. let me explain with an example:
I have a URL input
``
<input type="url" #url/>

<ng-container *ngIf="isUrl(url.value)">

<ngx-link-preview
[apiRoute]="'http://v2node.local/api/link-preview/test'"
[getApiEndpoint$]="apiCallbackFn"
[parseForLinksStr]="url.value"
[queryParamName]="'url'"
>

``
in this use case, the extension keeps sending requests on every found URL if le's say I wanted to get metadata for https://www.google.com I will be getting a list of previews for these links ( if they exist ) :
https://www.g.com
https://www.go.com
https://www.goo.com
https://www.goog.com
https://www.googl.com
https://www.google.com

image

It would be nice if there is an option for fetching only one link ( the last link for example). and make the fetching list of links optional

Not compatible with Angular 9

Getting the following message:

This likely means that the library (ngx-link-preview) which declares NgxLinkPreviewModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also, consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

@btxtiger

Error updating without `--force`

When tried installing, with this command: npm i ngx-link-preview. It failed saying:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/tslib
npm ERR!   tslib@"^2.1.0" from the root project
npm ERR!   tslib@"^2.1.0" from @angular/[email protected]
npm ERR!   node_modules/@angular/common
npm ERR!     @angular/common@"~12.0.5" from the root project
npm ERR!     peer @angular/common@">=6.0.0" from [email protected]
npm ERR!     node_modules/ngx-link-preview
npm ERR!       ngx-link-preview@"*" from the root project
npm ERR!     1 more (@angular/platform-browser)
npm ERR!   4 more (@angular/core, zone.js, @angular/platform-browser, @angular/animations)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer tslib@"^1.10.0" from [email protected]
npm ERR! node_modules/ngx-link-preview
npm ERR!   ngx-link-preview@"*" from the root project
npm ERR! 

Then forcing it to installed worked:

npm i --force ngx-link-preview

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.